From b28aa1f2c4c307289d4f51c6d4335834b5ddf6e9 Mon Sep 17 00:00:00 2001
From: Dividesbyzer0 <54127744+zoomdbz@users.noreply.github.com>
Date: Mon, 15 Jun 2026 02:21:01 -0400
Subject: [PATCH] fix(cookbook): allow local Windows Diffusers serving (#4077)
---
routes/shell_routes.py | 8 ++++++++
static/js/cookbook.js | 5 +++--
static/js/cookbookServe.js | 4 ++--
tests/test_cookbook_cpu_only_serve.py | 23 +++++++++++++++++++++++
tests/test_cookbook_package_detection.py | 9 +++++++++
5 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/routes/shell_routes.py b/routes/shell_routes.py
index 0eca092d4..b4e52325d 100644
--- a/routes/shell_routes.py
+++ b/routes/shell_routes.py
@@ -1063,6 +1063,13 @@ def setup_shell_routes() -> APIRouter:
"category": "Image",
"target": "remote",
},
+ {
+ "name": "transformers",
+ "pip": "transformers",
+ "desc": "Hugging Face model components used by SD/Flux pipelines and image tools",
+ "category": "Image",
+ "target": "remote",
+ },
{
"name": "rembg",
"pip": "rembg[gpu]",
@@ -1257,6 +1264,7 @@ def setup_shell_routes() -> APIRouter:
"sglang[all]",
"diffusers",
"diffusers[torch]",
+ "transformers",
"TTS",
"bark",
"faster-whisper",
diff --git a/static/js/cookbook.js b/static/js/cookbook.js
index 2abb263ba..cd1ae1b1f 100644
--- a/static/js/cookbook.js
+++ b/static/js/cookbook.js
@@ -597,7 +597,8 @@ export function _buildServeCmd(f, modelName, backend) {
} else if (backend === 'diffusers') {
const gpuStr = f.gpus?.trim();
if (gpuStr) cmd += `CUDA_VISIBLE_DEVICES=${gpuStr} `;
- cmd += `python3 scripts/diffusion_server.py --model ${modelName} --port ${f.port || '8100'}`;
+ const diffusersPy = _isWindows() ? 'python' : _py3Bin;
+ cmd += `${diffusersPy} scripts/diffusion_server.py --model ${modelName} --port ${f.port || '8100'}`;
if (f.diff_dtype && f.diff_dtype !== 'bfloat16') cmd += ` --dtype ${f.diff_dtype}`;
if (f.diff_device_map && f.diff_device_map !== 'balanced') cmd += ` --device-map ${f.diff_device_map}`;
if (f.diff_steps) cmd += ` --steps ${f.diff_steps}`;
@@ -718,7 +719,7 @@ async function _fetchDependencies() {
const data = await resp.json();
const pkgs = data.packages || [];
if (!pkgs.length) { list.innerHTML = '
No packages found
'; return; }
- const _winUnsupported = new Set(['diffusers', 'hf_transfer', 'vllm', 'rembg', 'gfpgan']);
+ const _winUnsupported = new Set(['hf_transfer', 'vllm', 'rembg', 'gfpgan']);
const _statusTag = (pkg, isLocal, isSystemDep, winBlocked) => {
if (winBlocked) return `N/A`;
diff --git a/static/js/cookbookServe.js b/static/js/cookbookServe.js
index 2a5cc5b5b..fe792554f 100644
--- a/static/js/cookbookServe.js
+++ b/static/js/cookbookServe.js
@@ -530,7 +530,7 @@ function _rerenderCachedModels() {
: (_lastUsed || (_isLegacyFlat ? _allSs : {}));
const detectedBackend = _detectBackend(m).backend;
const _allowedBackends = new Set(_isWindows()
- ? ['llamacpp']
+ ? ['llamacpp', 'diffusers']
: (_isMetal() ? ['llamacpp', 'ollama'] : ['vllm', 'sglang', 'llamacpp', 'ollama', 'diffusers']));
const defaultBackend = (ss._forceBackend && ss.backend && _allowedBackends.has(ss.backend))
? ss.backend
@@ -590,7 +590,7 @@ function _rerenderCachedModels() {
// Row 1: Backend + Server + Env
panelHtml += ``;
const _backendChoices = _isWindows()
- ? [['llamacpp','llama.cpp']]
+ ? [['llamacpp','llama.cpp'],['diffusers','Diffusers']]
: _isMetal()
// Diffusers (diffusion_server.py) is CUDA-only — omit it on Metal.
? [['llamacpp','llama.cpp'],['ollama','Ollama']]
diff --git a/tests/test_cookbook_cpu_only_serve.py b/tests/test_cookbook_cpu_only_serve.py
index ad4b795f8..b46c3e080 100644
--- a/tests/test_cookbook_cpu_only_serve.py
+++ b/tests/test_cookbook_cpu_only_serve.py
@@ -15,6 +15,7 @@ import re
from pathlib import Path
SRC = Path(__file__).resolve().parent.parent / "static/js/cookbook.js"
+SERVE_SRC = Path(__file__).resolve().parent.parent / "static/js/cookbookServe.js"
def test_cpu_only_drops_gpu_only_flags():
@@ -28,3 +29,25 @@ def test_cpu_only_drops_gpu_only_flags():
# The CUDA unified-memory env must be suppressed for CPU-only too.
assert "f.unified_mem && !_cpuOnly" in text, \
"GGML_CUDA_ENABLE_UNIFIED_MEMORY must be gated on !_cpuOnly"
+
+
+def test_diffusers_is_not_blocked_on_windows_dependencies_panel():
+ text = SRC.read_text(encoding="utf-8")
+
+ assert "const _winUnsupported = new Set(['hf_transfer', 'vllm', 'rembg', 'gfpgan']);" in text
+ assert "new Set(['diffusers'" not in text
+
+
+def test_diffusers_is_available_on_windows_serve_panel():
+ text = SERVE_SRC.read_text(encoding="utf-8")
+
+ assert "? ['llamacpp', 'diffusers']" in text
+ assert "? [['llamacpp','llama.cpp'],['diffusers','Diffusers']]" in text
+
+
+def test_windows_diffusers_uses_python_not_python3():
+ text = SRC.read_text(encoding="utf-8")
+
+ assert "const diffusersPy = _isWindows() ? 'python' : _py3Bin;" in text
+ assert "cmd += `${diffusersPy} scripts/diffusion_server.py" in text
+ assert "cmd += `python3 scripts/diffusion_server.py" not in text
diff --git a/tests/test_cookbook_package_detection.py b/tests/test_cookbook_package_detection.py
index 32aa7c93f..bf4378d07 100644
--- a/tests/test_cookbook_package_detection.py
+++ b/tests/test_cookbook_package_detection.py
@@ -23,6 +23,7 @@ def test_llama_cpp_maps_to_llama_cpp_python_distribution():
def test_extras_and_version_markers_are_stripped():
assert _pip_dist_name({"name": "diffusers", "pip": "diffusers[torch]"}) == "diffusers"
+ assert _pip_dist_name({"name": "transformers", "pip": "transformers"}) == "transformers"
assert _pip_dist_name({"name": "sglang", "pip": "sglang[all]"}) == "sglang"
assert _pip_dist_name({"name": "rembg", "pip": "rembg[gpu]"}) == "rembg"
assert _pip_dist_name({"name": "x", "pip": "foo>=1.2,<2"}) == "foo"
@@ -48,3 +49,11 @@ def test_route_uses_dist_name_helper_not_munged_import_name():
src = (Path(__file__).resolve().parents[1] / "routes" / "shell_routes.py").read_text(encoding="utf-8")
assert "importlib_metadata.version(_pip_dist_name(pkg))" in src
assert 'importlib_metadata.version(pkg["name"].replace("_", "-"))' not in src
+
+
+def test_transformers_is_listed_as_image_dependency():
+ src = (Path(__file__).resolve().parents[1] / "routes" / "shell_routes.py").read_text(encoding="utf-8")
+
+ assert '"name": "transformers"' in src
+ assert '"pip": "transformers"' in src
+ assert '"transformers",' in src