fix(cookbook): allow local Windows Diffusers serving (#4077)

This commit is contained in:
Dividesbyzer0
2026-06-15 02:21:01 -04:00
committed by GitHub
parent 33c26bab88
commit b28aa1f2c4
5 changed files with 45 additions and 4 deletions
+8
View File
@@ -1063,6 +1063,13 @@ def setup_shell_routes() -> APIRouter:
"category": "Image", "category": "Image",
"target": "remote", "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", "name": "rembg",
"pip": "rembg[gpu]", "pip": "rembg[gpu]",
@@ -1257,6 +1264,7 @@ def setup_shell_routes() -> APIRouter:
"sglang[all]", "sglang[all]",
"diffusers", "diffusers",
"diffusers[torch]", "diffusers[torch]",
"transformers",
"TTS", "TTS",
"bark", "bark",
"faster-whisper", "faster-whisper",
+3 -2
View File
@@ -597,7 +597,8 @@ export function _buildServeCmd(f, modelName, backend) {
} else if (backend === 'diffusers') { } else if (backend === 'diffusers') {
const gpuStr = f.gpus?.trim(); const gpuStr = f.gpus?.trim();
if (gpuStr) cmd += `CUDA_VISIBLE_DEVICES=${gpuStr} `; 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_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_device_map && f.diff_device_map !== 'balanced') cmd += ` --device-map ${f.diff_device_map}`;
if (f.diff_steps) cmd += ` --steps ${f.diff_steps}`; if (f.diff_steps) cmd += ` --steps ${f.diff_steps}`;
@@ -718,7 +719,7 @@ async function _fetchDependencies() {
const data = await resp.json(); const data = await resp.json();
const pkgs = data.packages || []; const pkgs = data.packages || [];
if (!pkgs.length) { list.innerHTML = '<div class="hwfit-loading">No packages found</div>'; return; } if (!pkgs.length) { list.innerHTML = '<div class="hwfit-loading">No packages found</div>'; 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) => { const _statusTag = (pkg, isLocal, isSystemDep, winBlocked) => {
if (winBlocked) return `<span class="cookbook-dep-tag cookbook-dep-na">N/A</span>`; if (winBlocked) return `<span class="cookbook-dep-tag cookbook-dep-na">N/A</span>`;
+2 -2
View File
@@ -530,7 +530,7 @@ function _rerenderCachedModels() {
: (_lastUsed || (_isLegacyFlat ? _allSs : {})); : (_lastUsed || (_isLegacyFlat ? _allSs : {}));
const detectedBackend = _detectBackend(m).backend; const detectedBackend = _detectBackend(m).backend;
const _allowedBackends = new Set(_isWindows() const _allowedBackends = new Set(_isWindows()
? ['llamacpp'] ? ['llamacpp', 'diffusers']
: (_isMetal() ? ['llamacpp', 'ollama'] : ['vllm', 'sglang', 'llamacpp', 'ollama', 'diffusers'])); : (_isMetal() ? ['llamacpp', 'ollama'] : ['vllm', 'sglang', 'llamacpp', 'ollama', 'diffusers']));
const defaultBackend = (ss._forceBackend && ss.backend && _allowedBackends.has(ss.backend)) const defaultBackend = (ss._forceBackend && ss.backend && _allowedBackends.has(ss.backend))
? ss.backend ? ss.backend
@@ -590,7 +590,7 @@ function _rerenderCachedModels() {
// Row 1: Backend + Server + Env // Row 1: Backend + Server + Env
panelHtml += `<div class="hwfit-serve-row">`; panelHtml += `<div class="hwfit-serve-row">`;
const _backendChoices = _isWindows() const _backendChoices = _isWindows()
? [['llamacpp','llama.cpp']] ? [['llamacpp','llama.cpp'],['diffusers','Diffusers']]
: _isMetal() : _isMetal()
// Diffusers (diffusion_server.py) is CUDA-only — omit it on Metal. // Diffusers (diffusion_server.py) is CUDA-only — omit it on Metal.
? [['llamacpp','llama.cpp'],['ollama','Ollama']] ? [['llamacpp','llama.cpp'],['ollama','Ollama']]
+23
View File
@@ -15,6 +15,7 @@ import re
from pathlib import Path from pathlib import Path
SRC = Path(__file__).resolve().parent.parent / "static/js/cookbook.js" 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(): 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. # The CUDA unified-memory env must be suppressed for CPU-only too.
assert "f.unified_mem && !_cpuOnly" in text, \ assert "f.unified_mem && !_cpuOnly" in text, \
"GGML_CUDA_ENABLE_UNIFIED_MEMORY must be gated on !_cpuOnly" "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
+9
View File
@@ -23,6 +23,7 @@ def test_llama_cpp_maps_to_llama_cpp_python_distribution():
def test_extras_and_version_markers_are_stripped(): def test_extras_and_version_markers_are_stripped():
assert _pip_dist_name({"name": "diffusers", "pip": "diffusers[torch]"}) == "diffusers" 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": "sglang", "pip": "sglang[all]"}) == "sglang"
assert _pip_dist_name({"name": "rembg", "pip": "rembg[gpu]"}) == "rembg" assert _pip_dist_name({"name": "rembg", "pip": "rembg[gpu]"}) == "rembg"
assert _pip_dist_name({"name": "x", "pip": "foo>=1.2,<2"}) == "foo" 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") 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(_pip_dist_name(pkg))" in src
assert 'importlib_metadata.version(pkg["name"].replace("_", "-"))' not 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