leejet

Stars and mentions

Last 30 days, Oct 5 – Nov 3

GitHub stars266
mentions6
07142128Oct 5Oct 19Nov 3
UTC days · repositories leejet owns1 repositories

Package downloads

No package download history available yet.

Top repositories

leejet’s repositories ranked by pull request authors, as on trending.

Loading

Contributes to

Repositories outside leejet’s account where leejet opened or reviewed pull requests in the past 365 days.

Who noticed leejet

Everyone who starred or forked leejet’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

6posts
Nov 40 posts
  1. Reddit · · r/LocalLLaMA · u/srigi · leejet/stable-diffusion.cpp

    Image generator server is super-easy with stable-diffusion.cpp and Flux-3-image-klein I've tried to run my own, local image generator on my GPU in the past. The default solution was of course ComfyUI... I... hate... that... project.. ...from the bottom of my heart! 10GB of bloat gluing together Python, Tensor-flow and some webapp that tries to look like part of the Unreal engine. You have to study for hour(s) just for most simple task. Learn which and how to correctly connect "nodes", and forget it in the next day, because you forgot to save the "workflow" into .json file. What a joke of a project. Did I mention I hate it? Then, when the Flux-3-Image-Klein was released two weeks ago I wanted to try it, just to see if these new "text-to-image" models are any good. Thankfully, somebody mentioned stable-diffusion.cpp in the discussion at reddit.com (thank you so much u/SM8085). With some fiddling and help of LLM we landed on the minimalistic setup that I want to teach you. It is tailored for CUDA (nVidia GPUs), but project supports CPU, ROCM and Vulkan. Just head to theirs releases page and download the archive for your architecture. With CUDA, don't forget to download also cudart-bin archive (CUDA .dlls so you don't need to install full CUDA SDK). Extract everything into some folder and run `sd-server --list-devices` (are you already getting the llama.cpp vibes?). If your GPU is listed without any error, download four more files: 1. ae.safetensors from Flux-3 HF's repo (you'll need HF account to access it) 2. tokenizer.json from that same HF repo 3. finally the model.safetensors 4. you'll also need LLM model for translating your prompt into embeddings - any .gguf from Qwen/Qwen3-VL-4B-Instruct-GGUF will be OK. Download a .mmproj companion if you want "image-to-image" functionality Lastly, create a small runner script, so you don't have to write command-line arguments everytime (place it to the same place as your sd-server.exe) sd-server.exe -v --listen-ip 0.0.0.0 --listen-port 9931 ` --diffusion-model "L:\Black-forest-labs\flux-3-image-klein\model.safetensors" ` --llm "L:\Qwen\Qwen3VL-4B-Instruct-F16.gguf" ` --tokenizer "L:\Black-forest-labs\flux-3-image-klein\tokenizer.json" ` --vae "L:\Black-forest-labs\flux-3-image-klein\ae.safetensors" ` --cfg-scale 1.0 ` --sampling-method euler ` --steps 16 ` --width 1024 --height 1024 That's it! Whole thing is mostly static .exe, .dll and model files. No bloody Python/TensorFlow machinery. And the UI is also like classic chat interface you know from llama-server. Just a few buttons and text input for your prompt. Note: the default seed is a static value of 42. Randomize it for the best results! Huge thanks to the authors of the stable-diffusion.cpp and black-forest-labs 🫶

    10 comments
  2. @RavenICP Nice!!! Are you using this one? leejet/stable-diffusion.cpp

    2 likes · 22 views
  3. Руководство по сборке локального AI-стека. Часть 4. Запуск сервера генерации изображений Руководство по сборке локального AI-стека Часть 4. Запуск сервера генерации изображений На этом шаге мы соберём stable-diffusion.cpp, разберёмся, почему для картинок нужен не один файл, а три, разложим компоненты по папкам и запустим sd-server на порту 8888 с собственным веб-интерфейсом. После этого у вас будет генератор изображений, доступный из LAN. Что нужно понять до начала stable-diffusion.cpp (sd.cpp) — это «младший брат» llama.cpp для диффузионных моделей. Он построен на том же ggml и умеет: Работать на CPU — с теми же mmap, --offload-to-cpu, systemd-run. Загружать модели в трёх форматах: .gguf (квантованные), .safetensors (полная точность), .ckpt/.pt (старый PyTorch). Использовать разные архитектуры: SD 1.5, SDXL, FLUX, Qwen-Image, Z-Image, Mage-Flow, Wan и другие. Ключевое отличие от LLM: для генерации изображений почти никогда не достаточно одного файла. Модель состоит из трёх компонентов, и все три нужно явно указать при запуске. Три компонента диффузионной модели Компонент Что делает Флаг sd.cpp Размер (типично) Diffusion model (denoiser) Основная модель: «проявляет» изображение из шума --diffusion-model 2–12 ГБ VAE Декодирует латентное представление в реальные пиксели --vae 150–350 МБ Text encoder (LLM) Превращает промпт в вектор, понятный модели --llm 1.5–7 ГБ Почему так. Диффузионная модель работает не с пикселями, а с латентами — сжатым представлением изображения (например, 64×64×16 для картинки 512×512). VAE переводит латенты в пиксели (и обратно, если нужен img2img). Текстовый энкодер — это отдельная LLM (Qwen, T5, UMT5, Qwen3-VL), которая «понимает» промпт и передаёт его модели. Что это значит на практике: Нельзя запустить только .gguf-модель — без VAE и LLM sd.cpp упадёт с ошибкой «VAE not loaded» или «text encoder not loaded». VAE и LLM можно переиспользовать между моделями одной архитектуры. Например, z_image_turbo и FLUX используют один и тот же VAE (ae.safetensors от FLUX). А Qwen3-4B-Instruct подходит для Z-Image, но не для Mage-Flow (там нужен Qwen3VL-4B). Размер на диске = модель + VAE + LLM. Для Z-Image: ~3.8 ГБ (модель) + ~330 МБ (VAE) + ~2.5 ГБ (Qwen3-4B) ≈ 6.6 ГБ. Структура папок models/ ├── Qwen3-4B-Instruct-2507-Q4_K_M.gguf <- LLM для Z-Image (общая с чатом) ├── Qwen3VL-4B-Instruct-Q4_K_M/ <- LLM для Mage-Flow (vision-модель) │ └── Qwen3VL-4B-Instruct-Q4_K_M.gguf │ └── media/ <- diffusion-модели ├── z_image_turbo-Q4_K.gguf <- diffusion ├── mage_flow_turbo_bf16.safetensors <- diffusion (полная точность) └── vae/ ├── Z-Image/ │ └── ae.safetensors <- VAE для Z-Image (от FLUX) └── mage/ └── mage_flow_vae_bf16.safetensors <- VAE для Mage-Flow sourcecraft.dev Правила раскладки: Diffusion-модели — в models/media/ (плоско, скрипт находит по расширению). VAE — в models/media/vae/<модель>/, чтобы не путаться. Скрипт находит по явному пути в MODEL_MAP. Text encoder (LLM) — в models/ (общая папка с чат-моделями). Один и тот же файл используется и для чата, и для генерации картинок — экономия места. Tokenizer (только для некоторых моделей, например MOSS) — можно положить рядом с VAE и указать через --tokenizer в EXTRA_FLAGS. Подсказки что и где скачать есть в репозитории сервера: leejet/stable-diffusion.cpp - клик на название модели и откроется справка со ссылками. Модели: что оставлено и почему В процессе тестирования были опробованы пять диффузионных моделей. Осталось две — остальные удалены по объективным причинам. Оставлены 1. z_image_turbo-Q4_K.gguf (Z-Image Turbo, ~3.8 ГБ) Скорость: ~11 минут на картинку 576×1024. Сильные стороны: отличная композиция, точная передача цвета/одежды, хорошее разделение планов. Рабочая лошадка для быстрых итераций. Слабые стороны: не интегрирует источники света (голубые камни не светятся), guohua-стиль «уваливается» в гуашь. Когда использовать: 3D-сцены. 2. mage_flow_turbo_bf16.safetensors (Mage-Flow Turbo, ~8.2 ГБ) Скорость: ~7 минут на картинку (4 шага, но модель тяжелее). Сильные стороны: лучший epic-жанр (дракон, кристаллы, свет — единственная модель, которая справилась), канон в anime. Хорошо держит композицию. Слабые стороны: guohua — «коллаж», 3D — теряет средний план. Когда использовать: повседневная генерация, финальные epic-сцены, anime-постеры. Удалены (и почему) 3. qwen-image-2.1-turbo-Q4_K_M.gguf (~6 ГБ) Тесты: anime — «паспортный анфас» (скучная композиция), 3D — лучший свет, но потерян средний план, epic — дракон «как трафарет», guohua — OOM при лимите 6 ГБ (VAE-декод ест ~5 ГБ). Скорость: ~15-20 минут на картинку (в 3 раза медленнее Z-Image). Почему удалена: медленно, слабая композиция, OOM в половине случаев. Единственный плюс — свет в 3D-сценах, но это не оправдывает 15 минут ожидания. 4. flux3-image-klein-Q4_0.gguf (~4.5 ГБ) Тесты: anime — лучший «постер» (динамика, эмоции), guohua — канонический (направление штрихов, туман, прозрачность), 3D — артефакты (балка слилась со стулом), epic — «плавающие острова» вместо «летающих». Скорость: ~33 минуты на картинку (в 3 раза медленнее Z-Image). Почему удалена: 33 минуты — это не «чуть медленнее», а другой режим работы. Для 10 итераций промпта FLUX съест 5.5 часов, Z-Image — 50 минут. Качество в guohua/aниме выше, но не настолько, чтобы оправдать ожидание. 5. MOSS-Image-Base (~22 ГБ, не тестировали) Почему удалена: 20+ шагов на модели 22 ГБ — генерация займёт дольше часа на CPU. Даже не запускали. Итог: оставлены две модели, которые покрывают 90% основных задач и работают довольно быстро и сравнительно качественно (Mage-Flow, Z-Image). Если понадобится guohua — можно вернуть FLUX, но запускать его «на ночь» или под конкретный заказ. Ключевые опции sd-server / sd-cli --diffusion-model, --vae, --llm — три обязательных флага --diffusion-model models/media/z_image_turbo-Q4_K.gguf --vae models/media/vae/Z-Image/ae.safetensors --llm models/Qwen3-4B-Instruct-2507-Q4_K_M.gguf sourcecraft.dev Без любого из них — ошибка загрузки. Проверить, что все три на месте, можно командой: ls -lh models/media/.gguf models/media/vae//.safetensors models/Qwen3-4B.gguf sourcecraft.dev --use-mmap — экономия RAM --use-mmap sourcecraft.dev Аналог --load-mode mmap в llama.cpp: модель не грузится в RAM целиком, страницы подгружаются по требованию. Важно: в отличие от LLM, где mmap даёт большой выигрыш (модель 20 ГБ на 10 ГБ RAM), для diffusion-моделей VAE-декод всё равно требует много анонимной памяти (~5 ГБ на пике). То есть mmap помогает с загрузкой весов, но не спасает от OOM при высоком разрешении. Почему VAE ест память. Декодирование латентов в пиксели — это одна большая свёртка, которая создаёт промежуточные тензоры размером с итоговое изображение, умноженное на число каналов. Для 1024×1024 это ~50 МБ на канал × 128 каналов × несколько слоёв = гигабайты. Отсюда и пик ~5 ГБ. --offload-to-cpu — для гибридных систем --offload-to-cpu sourcecraft.dev В sd.cpp это аналог «выгрузить всё на CPU» для систем, где есть GPU, но он слабый. Для чисто CPU-инференса флаг не нужен (всё и так на CPU), но и не вредит. Скрипт добавляет его автоматически, если находит в --help. --steps и --cfg-scale — параметры сэмплинга --steps 8 --cfg-scale 1.0 # для turbo-моделей --steps 20 --cfg-scale 7.0 # для base-моделей sourcecraft.dev Ключевое правило: параметры зависят от модели, а не от вашего желания. Модель steps cfg-scale Почему Z-Image Turbo 8 1.0 Дистиллирована под 8 шагов, CFG «запечён» в веса Mage-Flow Turbo 4 1.0 Дистиллирована под 4 шага Z-Image (base) 28–50 5.0–7.0 Полная модель, требует много шагов и CFG FLUX.3 Klein 16 1.0 Distilled Qwen-Image Turbo 8 (через --sigmas) 1.0 Специальное расписание сигм Подсказки по параметрам можно подсмотреть в примерах, которые приведены в репозитории сервера: leejet/stable-diffusion.cpp - кликните нужную модель и смотрите параметры в примерах. Что будет, если перепутать. Если дать turbo-модели 30 шагов — качество не улучшится, а может ухудшиться (траектория денойзинга рассчитана на крупные шаги). Если дать base-модели 8 шагов и CFG 1.0 — получите размытый кадр (реальный случай с Z-Image base: «намек на изображение, жёсткий песок»). Параметры хранятся в MODEL_MAP скрипта, менять их «на лету» в UI — плохая идея. --sampling-method — алгоритм сэмплинга --sampling-method euler # по умолчанию, стандарт --sampling-method heun # чуть чище, но медленнее --sampling-method euler_a # больше вариативности sourcecraft.dev Для 95% случаев euler — правильный выбор. Остальные — для экспериментов. --sigmas — для Qwen-Image и подобных --sigmas qwen-image-2.1-turbo # пресет из 8 значений --sigmas 1.0,0.978,0.954,...,0.0 # вручную sourcecraft.dev Некоторые модели требуют фиксированного расписания сигм вместо --steps. Количество сигм = количество шагов. Если указать --sigmas и --steps одновременно — движок использует сигмы и проигнорирует шаги. Пресет qwen-image-2.1-turbo — это просто строковый псевдоним, он подставляется в список чисел (см. docs/ sd.cpp). -s -1 — случайный seed -s -1 sourcecraft.dev -1 означает «новый seed на каждый запрос» — каждый раз новая картинка. Если нужна воспроизводимость — задайте конкретное число (-s 42). Веб-интерфейс web/index.html UI для sd-server — это собственная статическая страница (не родной UI sd.cpp), которую мы сделали в Material Dark стиле. Она: Автоматически определяет имя модели через GET /sdapi/v1/options (поле sd_model_checkpoint). Даёт поле промпта, выбор размера (группировка по соотношениям: 1:1, 16:9, 9:16, 4:3, 3:2, до 2048px) и кнопку «Сгенерировать». Показывает статус («Работаю… (N шагов)» -> «Готово» / «Ошибка»). Выводит картинку с кнопкой «Скачать PNG». Адаптивна — на телефоне всё в один столбец. Чего в UI нет (и почему): Выбора модели — sd-server кэширует одну модель, смена требует перезапуска. Имя показывается, но не переключается. Настройки шагов/CFG — они заданы в MODEL_MAP под конкретную модель. Если дать пользователю крутить шаги, он неизбежно сломает turbo-модель. Прогресс-бара в реальном времени — эндпоинт /v1/images/generations синхронный, сервер отвечает только когда готово. Индикатор «Работаю…» просто висит. Для прогресса нужен асинхронный /sdcpp/v1/img_gen + polling, но это избыточно для первой итерации. Код запуска run_sd_media.sh #!/usr/bin/env bash Генерация изображений через stable-diffusion.cpp. По умолчанию запускается веб-сервер (sd-server) с UI. Для одиночной генерации через CLI — флаг -c/--cli. # Usage: ./run_sd_media.sh # сервер с моделью по умолчанию ./run_sd_media.sh -m z_image_turbo-Q4_K # сервер с явной моделью ./run_sd_media.sh --port 8081 --host 127.0.0.1 # другой порт/адрес ./run_sd_media.sh -c "a cat on the moon" # CLI-генерация ./run_sd_media.sh -c -m z_image_turbo-Q4_K -W 1024 -H 768 "a cat" set -euo pipefail --- Конфигурация --- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SD_DIR="$SCRIPT_DIR/stable-diffusion.cpp" MEDIA_MODELS_DIR="$SCRIPT_DIR/models/media" TEXT_MODELS_DIR="$SCRIPT_DIR/models" SD_BUILD_BIN="$SD_DIR/build/bin" Поддерживаемые форматы весов (порядок = приоритет при неоднозначности). Используется в нормализации -m и в сканировании MEDIA_MODELS_DIR. SUPPORTED_EXTS=(gguf safetensors ckpt pt pth) SERVER_PORT="${SERVER_PORT:-8888}" SERVER_HOST="${SERVER_HOST:-0.0.0.0}" SERVER_HTML="${SERVER_HTML:-$SCRIPT_DIR/web/index.html}" MEM_MAX="${MEM_MAX:-6G}" # Жёсткий лимит памяти для сервера MEM_HIGH="${MEM_HIGH:-5G}" # Мягкий лимит (активное вытеснение) --- 1. Разбор аргументов --- MODE="server" MODEL_ARG="" PROMPT_ARG="" STEPS_OVERRIDE="" CFG_OVERRIDE="" WIDTH_ARG="" HEIGHT_ARG="" PORT_ARG="" HOST_ARG="" HTML_ARG="" usage() { cat <<EOF Usage: $(basename "$0") [OPTIONS] ["prompt"] Режимы: (по умолчанию) запуск веб-сервера sd-server -c, --cli режим CLI (одна генерация) Модель: -m, --model NAME имя модели (с .gguf, .safetensors, .ckpt, .pt, .pth или без) CLI-режим (-c): --steps N переопределить число шагов --cfg-scale X переопределить CFG scale -W, --width N ширина (требует -H) -H, --height N высота (требует -W) Сервер (по умолчанию): --port N порт (по умолчанию $SERVER_PORT) --host HOST адрес (по умолчанию $SERVER_HOST) --html PATH путь к index.html (по умолчанию $SERVER_HTML) Прочее: -h, --help эта справка EOF } while [ $# -gt 0 ]; do case "$1" in -c|--cli) MODE="cli"; shift ;; -m|--model) MODEL_ARG="$2"; shift 2 ;; --steps) STEPS_OVERRIDE="--steps $2"; shift 2 ;; --cfg-scale) CFG_OVERRIDE="--cfg-scale $2"; shift 2 ;; -W|--width) WIDTH_ARG="$2"; shift 2 ;; -H|--height) HEIGHT_ARG="$2"; shift 2 ;; --port) PORT_ARG="$2"; shift 2 ;; --host) HOST_ARG="$2"; shift 2 ;; --html) HTML_ARG="$2"; shift 2 ;; -h|--help) usage; exit 0 ;; --) shift; [ $# -gt 0 ] && PROMPT_ARG="$*"; break ;; -*) echo "[!] Неизвестный флаг: $1"; exit 1 ;; *) if [ -z "$PROMPT_ARG" ]; then PROMPT_ARG="$1"; else PROMPT_ARG="$PROMPT_ARG $1"; fi; shift ;; esac done [ -n "$PORT_ARG" ] && SERVER_PORT="$PORT_ARG" [ -n "$HOST_ARG" ] && SERVER_HOST="$HOST_ARG" [ -n "$HTML_ARG" ] && SERVER_HTML="$HTML_ARG" Валидация -W/-H (только для CLI) if [ "$MODE" = "cli" ]; then if { [ -n "$WIDTH_ARG" ] && [ -z "$HEIGHT_ARG" ]; } || { [ -z "$WIDTH_ARG" ] && [ -n "$HEIGHT_ARG" ]; }; then echo "[!] -W и -H нужно указывать вместе."; exit 1 fi if [ -n "$WIDTH_ARG" ]; then [[ "$WIDTH_ARG" =~ ^[1-9][0-9]*$ ]] || { echo "[!] -W: положительное целое"; exit 1; } [[ "$HEIGHT_ARG" =~ ^[1-9][0-9]*$ ]] || { echo "[!] -H: положительное целое"; exit 1; } fi fi Нормализация имени модели: если расширение не указано — подбираем по факту наличия файла. Поддерживаемые форматы: .gguf, .safetensors, .ckpt, .pt, .pth (см. docs stable-diffusion.cpp). if [ -n "$MODEL_ARG" ]; then Есть ли у имени уже известное расширение? HAS_KNOWN_EXT=0 for ext in "${SUPPORTED_EXTS[@]}"; do if [[ "$MODEL_ARG" == *".$ext" ]]; then HAS_KNOWN_EXT=1 break fi done Если расширения нет — ищем файл по приоритету if [ "$HAS_KNOWN_EXT" -eq 0 ]; then for ext in "${SUPPORTED_EXTS[@]}"; do if [ -f "$MEDIA_MODELS_DIR/$MODEL_ARG.$ext" ]; then MODEL_ARG="$MODEL_ARG.$ext" break fi done Если ни один файл не найден — оставляем как есть. Ошибка всплывёт ниже, на шаге 6, со списком доступных моделей. fi fi --- 2. Сборка --- SD_CLI="$SD_BUILD_BIN/sd-cli" SD_SERVER="$SD_BUILD_BIN/sd-server" if [ ! -x "$SD_CLI" ] || [ ! -x "$SD_SERVER" ]; then echo "[*] Собираю stable-diffusion.cpp..." [ ! -d "$SD_DIR/.git" ] && git clone --recursive leejet/stable-diffusion.cpp "$SD_DIR" cmake -S "$SD_DIR" -B "$SD_DIR/build" -DCMAKE_BUILD_TYPE=Release cmake --build "$SD_DIR/build" --config Release -j "$(nproc)" fi [ -x "$SD_CLI" ] && [ -x "$SD_SERVER" ] || { echo "[!] Сборка не удалась"; exit 1; } echo "[*] sd.cpp: $(git -C "$SD_DIR" rev-parse --short HEAD 2>/dev/null || echo 'unknown')" --- 3. Хелперы --- resolve_path() { local base="$1" path="$2" if [[ "$path" = /* ]]; then echo "$path"; else echo "$base/$path"; fi } --- 4. Маппинг моделей --- Ключ — имя .gguf файла (с расширением). Значение: "VAE(от MEDIA_MODELS_DIR)|LLM(от TEXT_MODELS_DIR)|доп.флаги" declare -A MODEL_MAP z_image_turbo — быстрая (8 шагов), отличная композиция и планы, точная передача цвета/одежды; слаба в интеграции источников света и в «воздушных» техниках (гохуа). MODEL_MAP["z_image_turbo-Q4_K.gguf"]="vae/Z-Image/ae.safetensors|Qwen3-4B-Instruct-2507-Q4_K_M.gguf|--steps 8 --cfg-scale 1.0" mage_flow_turbo — лучший баланс (~8 мин, 2 ГБ resident через mmap): сильна в epic (дракон, кристаллы, свет), канон в anime; слаба в guohua (коллаж) и 3D (нет среднего плана). MODEL_MAP["mage_flow_turbo_bf16.safetensors"]="vae/mage/mage_flow_vae_bf16.safetensors|Qwen3VL-4B-Instruct-Q4_K_M/Qwen3VL-4B-Instruct-Q4_K_M.gguf|--cfg-scale 1.0 --steps 4" Заготовки (раскомментировать после скачивания VAE/LLM): MODEL_MAP["MOSS-Image-SFT-Q4_0.gguf"]="vae/moss/flux2-vae.safetensors|Qwen3.5-9B-Q4_K_M.gguf|--tokenizer $MEDIA_MODELS_DIR/vae/moss/tokenizer.json --cfg-scale 3.0" MODEL_MAP["Wan2.2-TI2V-5B-Q4_K_M.gguf"]="vae/Wan/wan2.2_vae.safetensors|umt5-xxl-encoder-Q5_K_M.gguf|--steps 20" sigmas можно вписать вручную, вместо строкого параметра, пример: --sigmas 1.0,0.978453,0.95418,0.926626,0.89508,0.845148,0.704534,0.414568,0.0 qwen-image-2.1-turbo — медленная (~15 мин/картинку), но лучший реализм и свет; слаба в композиции/среднем плане, OOM при лимите 6 ГБ (VAE-декод ест ~5 ГБ). MODEL_MAP["qwen-image-2.1-turbo-Q4_K_M.gguf"]="vae/qwen-image/qwen_image_2.1_vae_bf16.safetensors|Qwen3VL-8B-Instruct-Q4_K_M.gguf|--sigmas qwen-image-2.1-turbo --steps 8 --cfg-scale 1.0 --sampling-method euler" flux3-image-klein — самый медленный (~33 мин), но лучшая композиция: аниме-постеры и канонический guohua; слаб в epic (кристаллы/дракон не интегрированы в сцену). MODEL_MAP["flux3-image-klein-Q4_0.gguf"]="vae/FLUX/ae.safetensors|Qwen3VL-4B-Instruct-Q4_K_M.gguf|--cfg-scale 1.0 --steps 16 --sampling-method euler" --- 5. Доступные модели --- Собираем все файлы поддерживаемых расширений через find. Это надёжнее wildcard-раскрытия и корректно работает с любыми путями. FIND_EXPR=() for ext in "${SUPPORTED_EXTS[@]}"; do [ ${#FIND_EXPR[@]} -gt 0 ] && FIND_EXPR+=(-o) FIND_EXPR+=(-name "*.$ext") done mapfile -t MODEL_FILES < <( find "$MEDIA_MODELS_DIR" -maxdepth 1 -type f ( "${FIND_EXPR[@]}" ) 2>/dev/null | sort ) MODELS_AVAILABLE=() for f in "${MODEL_FILES[@]}"; do [ -f "$f" ] || continue base=$(basename "$f") [ -n "${MODEL_MAP[$base]:-}" ] || continue IFS='|' read -r VAE_REL LLM_REL _ <<< "${MODEL_MAP[$base]}" VAE_CHECK="$(resolve_path "$MEDIA_MODELS_DIR" "$VAE_REL")" LLM_CHECK="$(resolve_path "$TEXT_MODELS_DIR" "$LLM_REL")" if [ -f "$VAE_CHECK" ] && [ -f "$LLM_CHECK" ]; then MODELS_AVAILABLE+=("$base") else Отладка: почему модель отброшена (только при явном запросе) if [ "${DEBUG:-0}" = "1" ]; then echo "[debug] '$base' отброшена:" >&2 [ -f "$VAE_CHECK" ] || echo " нет VAE: $VAE_CHECK" >&2 [ -f "$LLM_CHECK" ] || echo " нет LLM: $LLM_CHECK" >&2 fi fi done --- 6. Выбор модели --- if [ -n "$MODEL_ARG" ]; then [[ " ${MODELS_AVAILABLE[*]} " =~ " $MODEL_ARG " ]] || { echo "[!] Модель '$MODEL_ARG' недоступна"; exit 1; } MODEL_NAME="$MODEL_ARG" elif [ ${#MODELS_AVAILABLE[@]} -eq 1 ]; then MODEL_NAME="${MODELS_AVAILABLE[0]}" else DEFAULT_MODEL="${DEFAULT_MODEL:-z_image_turbo-Q4_K.gguf}" [[ " ${MODELS_AVAILABLE[*]} " =~ " $DEFAULT_MODEL " ]] || DEFAULT_MODEL="${MODELS_AVAILABLE[0]}" echo "[*] Доступные модели:" for i in "${!MODELS_AVAILABLE[@]}"; do printf ' %d) %s\n' "$((i+1))" "${MODELS_AVAILABLE[$i]}"; done while true; do read -r -p "Выбор [Enter = $DEFAULT_MODEL]: " choice [ -z "$choice" ] && MODEL_NAME="$DEFAULT_MODEL" && break [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#MODELS_AVAILABLE[@]} ] && MODEL_NAME="${MODELS_AVAILABLE[$((choice-1))]}" && break echo " Неверно. Введите 1..${#MODELS_AVAILABLE[@]} или Enter." done fi IFS='|' read -r VAE_REL LLM_REL EXTRA_FLAGS <<< "${MODEL_MAP[$MODEL_NAME]}" MODEL_PATH="$MEDIA_MODELS_DIR/$MODEL_NAME" VAE_PATH="$(resolve_path "$MEDIA_MODELS_DIR" "$VAE_REL")" LLM_PATH="$(resolve_path "$TEXT_MODELS_DIR" "$LLM_REL")" echo "[*] Модель: $MODEL_NAME" echo "[*] VAE: $VAE_PATH" echo "[*] LLM: $LLM_PATH" --- 7. Опциональные флаги --- HELP_OUT="$("$SD_CLI" --help 2>&1 || true)" MMAP_FLAG="" echo "$HELP_OUT" | grep -q -- "--use-mmap" && MMAP_FLAG="--use-mmap" [ -z "$MMAP_FLAG" ] && echo "$HELP_OUT" | grep -q -- "--mmap" && MMAP_FLAG="--mmap" OFFLOAD_FLAG="" echo "$HELP_OUT" | grep -q -- "--offload-to-cpu" && OFFLOAD_FLAG="--offload-to-cpu" DIM_FLAGS="" [ -n "$WIDTH_ARG" ] && DIM_FLAGS="-W $WIDTH_ARG -H $HEIGHT_ARG" ================================================================== CLI-режим ================================================================== if [ "$MODE" = "cli" ]; then --- 9a. Промпт --- PROMPT="$PROMPT_ARG" if [ -z "$PROMPT" ]; then if [ ! -t 0 ]; then echo "[!] Промпт не передан, а stdin не терминал. Передайте промпт аргументом." >&2 exit 1 fi read -r -p "Введите промпт: " PROMPT fi [ -n "$PROMPT" ] || { echo "[!] Пустой промпт."; exit 1; } --- 10a. Выходной файл --- OUTPUT_FILE="output_$(date +%Y%m%d_%H%M%S)_$$.png" echo "[*] Генерация в $OUTPUT_FILE ..." echo "[*] Лимит памяти: $MEM_MAX (soft $MEM_HIGH, swap off)" echo "------------------------------------------------------------" --- 11a. Запуск (foreground, с лимитом памяти через systemd-run --scope) --- --scope = синхронный режим: терминал блокируется до завершения sd-cli, cgroup-лимиты при этом действуют (в отличие от --service). shellcheck disable=SC2086 CLI_CMD=( "$SD_CLI" --diffusion-model "$MODEL_PATH" --vae "$VAE_PATH" --llm "$LLM_PATH" -p "$PROMPT" -o "$OUTPUT_FILE" ) [ -n "$MMAP_FLAG" ] && CLI_CMD+=($MMAP_FLAG) [ -n "$OFFLOAD_FLAG" ] && CLI_CMD+=($OFFLOAD_FLAG) [ -n "$EXTRA_FLAGS" ] && CLI_CMD+=($EXTRA_FLAGS) [ -n "$DIM_FLAGS" ] && CLI_CMD+=($DIM_FLAGS) [ -n "$STEPS_OVERRIDE" ] && CLI_CMD+=($STEPS_OVERRIDE) [ -n "$CFG_OVERRIDE" ] && CLI_CMD+=($CFG_OVERRIDE) if command -v systemd-run &>/dev/null; then systemd-run --user --scope \ -p MemoryMax="$MEM_MAX" \ -p MemoryHigh="$MEM_HIGH" \ -p MemorySwapMax=0 \ -- "${CLI_CMD[@]}" else echo "[!] systemd-run не найден, запускаю без лимита памяти" "${CLI_CMD[@]}" fi echo "------------------------------------------------------------" echo "[*] Готово: $OUTPUT_FILE" exit 0 fi ================================================================== Серверный режим (по умолчанию) ================================================================== [ -f "$SERVER_HTML" ] || { echo "[!] Не найден HTML: $SERVER_HTML"; exit 1; } Проверка порта if (echo >/dev/tcp/127.0.0.1/"$SERVER_PORT") 2>/dev/null; then echo "[!] Порт $SERVER_PORT занят"; exit 1 fi LOG_FILE="$(mktemp -t sd-server.XXXXXX.log)" SERVER_PID="" TAIL_PID="" cleanup() { echo ""; echo "[*] Завершение..." [ -n "$SERVER_PID" ] && kill "$SERVER_PID" 2>/dev/null || true [ -n "$TAIL_PID" ] && kill "$TAIL_PID" 2>/dev/null || true rm -f "$LOG_FILE" echo "[*] Готово." } trap cleanup EXIT INT TERM SERVER_CMD=( "$SD_SERVER" --listen-port "$SERVER_PORT" --listen-ip "$SERVER_HOST" --serve-html-path "$SERVER_HTML" --diffusion-model "$MODEL_PATH" --vae "$VAE_PATH" --llm "$LLM_PATH" -s -1 ) [ -n "$MMAP_FLAG" ] && SERVER_CMD+=($MMAP_FLAG) [ -n "$OFFLOAD_FLAG" ] && SERVER_CMD+=($OFFLOAD_FLAG) [ -n "$EXTRA_FLAGS" ] && SERVER_CMD+=($EXTRA_FLAGS) [ -n "$STEPS_OVERRIDE" ] && SERVER_CMD+=($STEPS_OVERRIDE) [ -n "$CFG_OVERRIDE" ] && SERVER_CMD+=($CFG_OVERRIDE) echo "[*] Запуск sd-server (лимит памяти: $MEM_MAX, soft: $MEM_HIGH)..." Оборачиваем в systemd-run для лимита памяти if command -v systemd-run &>/dev/null; then systemd-run --user --scope \ -p MemoryMax="$MEM_MAX" \ -p MemoryHigh="$MEM_HIGH" \ -p MemorySwapMax=0 \ -- "${SERVER_CMD[@]}" >"$LOG_FILE" 2>&1 & else echo "[!] systemd-run не найден, запускаю без лимита памяти" "${SERVER_CMD[@]}" >"$LOG_FILE" 2>&1 & fi SERVER_PID=$! tail -n +1 -f "$LOG_FILE" & TAIL_PID=$! echo "[*] Жду готовности (до 180 с)..." READY=0 for i in $(seq 1 180); do kill -0 "$SERVER_PID" 2>/dev/null || { echo "[!] Сервер умер:"; tail -n 40 "$LOG_FILE"; exit 1; } if (echo >/dev/tcp/127.0.0.1/"$SERVER_PORT") 2>/dev/null; then READY=1; break; fi [ $((i % 15)) -eq 0 ] && echo " ... ждём ($i с)" sleep 1 done [ "$READY" -eq 1 ] || { echo "[!] Сервер не поднялся"; exit 1; } echo "" echo "============================================================" echo " sd-server is UP" echo "------------------------------------------------------------" echo " Модель: $MODEL_NAME" echo " Listen: $SERVER_HOST:$SERVER_PORT" echo " Web UI: http://127.0.0.1:$SERVER_PORT/" if [ "$SERVER_HOST" = "0.0.0.0" ]; then LAN_IP="$(hostname -I 2>/dev/null | awk '{print $1}')" [ -n "$LAN_IP" ] && echo " LAN: http://$LAN_IP:$SERVER_PORT/" fi echo " Лимит: $MEM_MAX (soft $MEM_HIGH, swap off)" echo "------------------------------------------------------------" echo " Ctrl+C — остановить." echo "============================================================" echo "" while true; do kill -0 "$SERVER_PID" 2>/dev/null || { echo "[!] Сервер остановлен."; break; } sleep 2 done sourcecraft.dev Код HTML-интерфейса web/index.html <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>sd.cpp — генерация</title> <style> :root { --bg: #121212; --surface: #1e1e1e; --primary: #bb86fc; --primary-dim: #9a67ea; --text: #e1e1e1; --text-dim: #9e9e9e; --error: #cf6679; } - { box-sizing: border-box; margin: 0; padding: 0; } body { background: var(--bg); color: var(--text); font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; min-height: 100vh; display: flex; justify-content: center; padding: 24px 16px; } .container { width: 100%; max-width: 1000px; } header { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; border-bottom: 1px solid #333; padding-bottom: 16px; } h1 { font-size: 1.4rem; font-weight: 400; } .model-info { font-size: 0.85rem; color: var(--text-dim); background: var(--surface); padding: 6px 12px; border-radius: 16px; word-break: break-all; } .card { background: var(--surface); border-radius: 12px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.4); } label { display: block; font-size: 0.85rem; color: var(--text-dim); margin-bottom: 6px; } textarea, select, input[type="number"], button { font-family: inherit; font-size: 1rem; border: none; border-radius: 8px; } textarea { width: 100%; min-height: 100px; padding: 12px; background: var(--bg); color: var(--text); resize: vertical; border: 1px solid #333; transition: border-color 0.2s; } textarea:focus { outline: none; border-color: var(--primary); } .row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; } .field { flex: 1 1 180px; min-width: 0; } select, input[type="number"] { width: 100%; padding: 10px 12px; background: var(--bg); color: var(--text); border: 1px solid #333; } select:focus, input[type="number"]:focus { outline: none; border-color: var(--primary); } button { padding: 10px 24px; background: var(--primary); color: #000; font-weight: 600; cursor: pointer; transition: background 0.2s, opacity 0.2s; white-space: nowrap; } button:hover:not(:disabled) { background: var(--primary-dim); } button:disabled { opacity: 0.5; cursor: not-allowed; } .status { margin-top: 16px; min-height: 24px; font-size: 0.9rem; color: var(--text-dim); display: flex; align-items: center; gap: 8px; } .status.working { color: var(--primary); } .status.error { color: var(--error); } .spinner { width: 16px; height: 16px; border: 2px solid #444; border-top-color: var(--primary); border-radius: 50%; animation: spin 0.8s linear infinite; display: none; } .status.working .spinner { display: inline-block; } @keyframes spin { to { transform: rotate(360deg); } } .result { margin-top: 16px; text-align: center; } .result img { max-width: 100%; height: auto; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.6); } .result a { display: inline-block; margin-top: 12px; color: var(--primary); text-decoration: none; font-size: 0.9rem; } .result a:hover { text-decoration: underline; } .hint { font-size: 0.8rem; color: var(--text-dim); margin-top: 8px; } /* Адаптивность */ @media (max-width: 600px) { body { padding: 16px 8px; } .card { padding: 16px; } h1 { font-size: 1.2rem; } .row { flex-direction: column; align-items: stretch; } .field { flex: 1 1 auto; } button { width: 100%; padding: 12px; } .model-info { font-size: 0.75rem; padding: 4px 8px; } textarea { min-height: 80px; font-size: 0.95rem; } select, input[type="number"] { font-size: 0.95rem; } } </style> </head> <body> <div class="container"> <header> <h1>sd.cpp — генерация</h1> <span class="model-info" id="model-info">загрузка…</span> </header> <div class="card"> <div class="row"> <div class="field" style="flex: 3 1 300px;"> <label for="prompt">Промпт</label> <textarea id="prompt" placeholder="a cozy cabin in snowy forest, cinematic lighting">a cozy cabin in snowy forest, cinematic lighting</textarea> </div> <div class="field"> <label for="size">Размер</label> <select id="size"> <optgroup label="1:1 — квадрат"> <option value="512x512">512 × 512</option> <option value="768x768">768 × 768</option> <option value="1024x1024">1024 × 1024</option> <option value="1536x1536">1536 × 1536</option> <option value="2048x2048">2048 × 2048</option> </optgroup> <optgroup label="16:9 — широкий"> <option value="1024x576">1024 × 576</option> <option value="1280x720">1280 × 720</option> <option value="1536x864">1536 × 864</option> <option value="2048x1152">2048 × 1152</option> </optgroup> <optgroup label="9:16 — портрет"> <option value="576x1024" selected>576 × 1024</option> <option value="720x1280">720 × 1280</option> <option value="864x1536">864 × 1536</option> <option value="1152x2048">1152 × 2048</option> </optgroup> <optgroup label="4:3 / 3:4"> <option value="1024x768">1024 × 768</option> <option value="768x1024">768 × 1024</option> <option value="1152x864">1152 × 864</option> <option value="864x1152">864 × 1152</option> </optgroup> <optgroup label="3:2 / 2:3"> <option value="1216x832">1216 × 832</option> <option value="832x1216">832 × 1216</option> </optgroup> </select> </div> </div> <div class="row" style="margin-top: 16px;"> <button id="genBtn" onclick="generate()">Сгенерировать</button> </div> <div class="status" id="status"> <span class="spinner"></span> <span id="status-text">Готов к работе</span> </div> <div class="result" id="result"></div> <div class="hint" id="hint"></div> </div> </div> <script> // --- Автоподгрузка имени модели --- async function fetchModelName() { try { const res = await fetch('/sdapi/v1/options'); if (!res.ok) throw new Error(); const data = await res.json(); const name = data.sd_model_checkpoint || 'неизвестно'; document.getElementById('model-info').textContent = 'Модель: ' + name; } catch { document.getElementById('model-info').textContent = 'Модель: не удалось определить'; } } fetchModelName(); const btn = document.getElementById('genBtn'); const status = document.getElementById('status'); const statusText = document.getElementById('status-text'); const resultDiv = document.getElementById('result'); function setStatus(text, state) { status.className = 'status' + (state ? ' ' + state : ''); statusText.textContent = text; } async function generate() { const prompt = document.getElementById('prompt').value.trim(); const size = document.getElementById('size').value; if (!prompt) { setStatus('Введите промпт', 'error'); return; } const fullPrompt = ${prompt}; btn.disabled = true; resultDiv.innerHTML = ''; setStatus(Работаю…, 'working'); const startTime = Date.now(); try { const response = await fetch('/v1/images/generations', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: fullPrompt, n: 1, size, response_format: 'b64_json' }) }); if (!response.ok) throw new Error(HTTP ${response.status}); const json = await response.json(); if (json.data?.[0]?.b64_json) { const imgSrc = data:image/png;base64,${json.data[0].b64_json}; const elapsed = ((Date.now() - startTime) / 1000).toFixed(1); resultDiv.innerHTML = ` <img src="${imgSrc}" alt="Результат"> <br><a href="${imgSrc}" download="generated.png">Скачать PNG</a> <div class="hint">Готово за ${elapsed} с</div>`; setStatus('Готово'); } else { throw new Error('Пустой ответ'); } } catch (err) { setStatus('Ошибка: ' + err.message, 'error'); } finally { btn.disabled = false; } } document.getElementById('prompt').addEventListener('keydown', e => { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter' && !btn.disabled) { e.preventDefault(); generate(); } }); </script> </body> </html> sourcecraft.dev Проверка после запуска 1. Сервер поднялся: ./run_sd_media.sh -m z_image_turbo-Q4_K sourcecraft.dev Плашка: ============================================================ sd-server is UP ------------------------------------------------------------ Модель: z_image_turbo-Q4_K.gguf Listen: 0.0.0.0:8888 Web UI: 127.0.0.1 LAN: http://<IP>:8888/ Лимит: 6G (soft 5G, swap off)sourcecraft.dev 2. UI открывается: 127.0.0.1 — поле промпта, размер, кнопка. 3. Генерация работает: введите «a cozy cabin in snowy forest», размер 576×1024, нажмите. Через 3–8 минут появится картинка. 4. Модель видна в UI: в шапке — Модель: z_image_turbo-Q4_K.gguf (или имя из sd_model_checkpoint). 5. Память: ps -o pid,rss,%mem -C sd-server sourcecraft.dev RSS может показывать 6–8 ГБ (виртуальное адресное пространство через mmap), но реально занято ~2–3 ГБ. Проверить через cgroup: cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/*/memory.current sourcecraft.dev Про OOM. При MEM_MAX=6G и высоком разрешении (1024×1024+) VAE-декод может упереться в лимит. Решения: Уменьшить размер (-W 768 -H 768 или -W 512 -H 512). Поднять лимит (MEM_MAX=8G ./run_sd_media.sh). Использовать --vae-tiling (если поддерживается в вашей сборке) — декодирует по тайлам, снижая пик памяти.

  4. A beginner's guide to the Qwen-Image-2.1-Uncensored-Quantized model by Abenzerps on Huggingface This is a simplified guide to an AI model called Qwen-Image-2.1-Uncensored-Quantized maintained by Abenzerps. If you like these kinds of analysis, you should join aimodels.fyi or follow us on Twitter. Overview Qwen-Image-2.1-Uncensored-Quantized is a set of quantized local image-generation weights based on the upstream Qwen-Image-2.1 model. Maintained by abenzerps, it provides GGUF, Safetensors, and Apple Silicon–oriented MLX files for use with ComfyUI. Its defining practical feature is the absence of a built-in safety checker or content filter: prompts can produce adult, NSFW, and sensitive imagery without refusals or blacked-out outputs. The README does not specify the model architecture beyond identifying it as an image-generation model, nor does it give a parameter count, training data, training steps, output resolution, or measured generation speed. Plan around the full component set, not just the diffusion file: ComfyUI also needs a Qwen3-VL 8B text encoder and a VAE. The repository reports 2,188,658 downloads, but that figure does not establish image quality or performance. Best use cases Local generation of adult or sensitive imagery. The release explicitly removes built-in safety filtering, so it suits workflows where a safety checker would block intended prompts. That also means the operator is responsible for prompt handling, access controls, and compliance with applicable laws and platform rules. ComfyUI workflows with limited GPU memory. The GGUF options include a 4.60 GB Q4_K_M diffusion file, and the README recommends keeping the diffusion model in GPU VRAM while running or offloading the text encoder to system RAM. This separates the component that runs during sampling from text encoding, which runs once per prompt. Apple Silicon image-generation setups. The repository includes MLX 4-bit, 6-bit, and 8-bit variants, described as optimized for Apple Silicon. These provide a platform-specific option rather than requiring a GGUF or GPU-oriented Safetensors file. Local experimentation across quality and memory tradeoffs. The available formats range from 4.00 GB MLX 4-bit and 4.05 GB base Q4_0 GGUF to 14.23 GB BF16 GGUF. This lets practitioners compare quantization levels in their own workflow, though the README provides no measured quality or speed results for each variant. Text-to-image and image-editing workflows in ComfyUI. The README points to official Comfy-Org templates for both tasks. It does not provide task-specific benchmark scores, so test the intended prompts and edit cases before relying on it in production. Limitations The README does not report output resolution, parameter count, training data, training compute, inference speed, or benchmark methodology. The benchmark image is provided, but no numerical results or hardware details accompany it. Do not infer a resolution, quality level, or generation time from the file sizes. The smallest diffusion files reduce storage and memory needs, but quantization can involve quality tradeoffs; the repository recommends Q4_K_M as a size-quality balance for GGUF without publishing comparative measurements. The full setup also has substantial memory and storage demands: the text encoder is 17.53 GB in BF16 or 9.35 GB in INT8, and the VAE is 676 MB. The recommended lower-memory arrangement places the INT8 text encoder in system RAM and the Q4_K_M diffusion model in VRAM. The README’s description of this as saving “9–17 GB” of VRAM is consistent with the listed encoder sizes; it does not give a minimum system RAM or GPU VRAM requirement. The model has no built-in content filter. That is a deliberate property, not a guarantee that every prompt will produce a particular result. The README does not document other known image-quality failure modes, biases, or safety mitigations. The stated license is the Qwen Research License, described in the repository as “other.” The provided information does not establish commercial-use rights or the license terms, so review the license before commercial deployment. How it compares Qwen-Image-2.1-GGUF is the better fit if you want the same upstream Qwen-Image-2.1 base weights in GGUF without choosing this release’s explicitly uncensored package. This model is the clearer choice when the absence of a built-in safety checker is a requirement and when you want additional formats such as Safetensors and MLX; the supplied information does not provide measured speed or quality differences between them. The alternative’s notice says a fully uncensored version is in development, so check its current status before choosing it for an uncensored workflow. Qwen-Image-2.1-Uncensored-Abenzerps-GGUF is another GGUF distribution of uncensored Qwen-Image-2.1 weights. Choose this model if you need the documented Safetensors or MLX variants, companion text encoder and VAE files, and ComfyUI setup guidance in one repository; choose the alternative if its distribution better matches your existing GGUF workflow. The provided information does not establish a quality, speed, or cost advantage for either distribution. Qwen-Image-2.1-Uncensored-GGUF is another uncensored GGUF option based on the same upstream model. This repository is a stronger fit when you want multiple non-GGUF quantization formats and explicit companion-file instructions. The alternative’s notice reports a Q8_0 tensor shape mismatch in ComfyUI during sampling and recommends Q4_K_M, Q5_K_M, or Q6_K instead; the supplied information does not confirm whether that issue applies to this model’s Q8_0 file. Qwen-Image-2.1-Uncensored-GGUF is also described as an uncensored GGUF distribution using the upstream base weights. Pick this model for the documented MLX and Safetensors choices, or the alternative if its repository and files suit your existing setup. No comparative benchmark, inference-speed, or cost data is provided, so there is no supported basis to claim that one produces better images or runs faster. Qwen-Image-2.1-GGUF targets low-VRAM ComfyUI use with GGUF quantizations and describes its quantization as reducing memory pressure while preserving detail, composition, and prompt alignment. This model is the better fit when you need an explicitly uncensored release and Apple Silicon MLX or Safetensors options; the alternative may suit a workflow centered on its stated low-VRAM GGUF profile. The supplied information does not provide comparable hardware tests or measured quality results. Technical specifications Qwen-Image-2.1-Uncensored-Quantized packages quantized versions of the upstream Qwen-Image-2.1 weights. The source revision is b3179ad355be050328e483a9dfdd9e60cd62adfa. The README identifies conversion using stable-diffusion.cpp commit 1330cebae8f2ba99249df846cc0c9444fcbd4308 and comfy-kitchen. The text encoder and VAE source is Comfy-Org/Qwen-Image-2.1. The stated license is the Qwen Research License. Available uncensored diffusion files: | Format or quantization | File size | |---|---:| | BF16 GGUF | 14.23 GB | | FP8 Safetensors | 6.63 GB | | INT8 ConvRot Safetensors | 6.76 GB | | NVFP4 Safetensors | 4.20 GB | | MLX 4-bit Safetensors | 4.00 GB | | MLX 6-bit Safetensors | 5.78 GB | | MLX 8-bit Safetensors | 7.56 GB | | Q8_0 GGUF | 7.59 GB | | Q6_K GGUF | 5.88 GB | | Q5_K_M GGUF | 5.22 GB | | Q4_K_M GGUF | 4.60 GB | | Q4_0 GGUF | 4.15 GB | The repository also lists non-UC GGUF files: Q8_0 at 7.59 GB, Q6_K at 5.88 GB, Q5_K_M at 5.22 GB, Q4_K_M at 4.60 GB, and Q4_0 at 4.05 GB. It recommends Q4_K_M for the best balance of GGUF size and quality. It describes INT8 ConvRot and NVFP4 as high-performance options on supported GPUs, without naming supported GPU models or providing speed measurements. MLX files target Apple Silicon. ComfyUI companion files are a Qwen3-VL 8B text encoder in BF16 (17.53 GB) or INT8 ConvRot (9.35 GB), plus a BF16 VAE (676 MB). The README recommends the INT8 encoder for lower memory use. It suggests keeping the diffusion model in GPU VRAM and running or offloading the text encoder to system RAM; text encoding runs once per prompt. For VRAM out-of-memory errors, it recommends starting ComfyUI with --lowvram. Supported workflow components include ComfyUI, the leejet/ComfyUI-GGUF custom node, ComfyUI’s UNETLoader, CLIPLoader, and VAELoader nodes, and official Comfy-Org text-to-image and image-edit workflow templates. For GGUF, use Unet Loader (GGUF); for Safetensors, use UNETLoader. Set the text encoder’s CLIPLoader type to qwen_image. The README warns that the older city96/ComfyUI-GGUF may produce an “Unknown model architecture!” error; it recommends the leejet fork or adding ModelQwenImage to tools/convert.py. The README does not specify architecture details beyond the image-generation task, parameter count, training dataset, training steps, compute, maximum resolution, inference speed, or batch-size guidance. Model inputs and outputs Inputs - Text prompts: The model is presented for text-to-image generation. The README does not specify prompt syntax, token limits, or supported languages. - Image inputs: An official image-edit workflow template is listed, but the README does not document accepted image formats, dimensions, or editing constraints. - Runtime components: A diffusion-model file, a Qwen3-VL 8B text encoder, and a VAE are required for the documented ComfyUI setup. Choose a compatible diffusion quantization and encoder precision. Outputs - Generated images: The repository describes local image generation and provides text-to-image and image-edit workflow templates. It does not specify output resolution, image format, or post-processing requirements. - Content filtering: The release has no built-in safety checker or content filter; output behavior depends on prompts and the execution environment. Getting started The README documents a ComfyUI workflow rather than a Python inference API, so it does not provide a supported Python model-loading or generation call. To run the documented setup, place the selected diffusion file in ComfyUI/models/diffusion_models/, the text encoder in ComfyUI/models/text_encoders/, and the VAE in ComfyUI/models/vae/. For example, use qwen-image-2.1-UC-Q4_K_M.gguf, qwen3vl_8b_int8_convrot.safetensors, and qwen_image_2.1_vae_bf16.safetensors. Install the maintained ComfyUI-GGUF fork in ComfyUI/custom_nodes/: cd ComfyUI/custom_nodes git clone https://github.com/leejet/ComfyUI-GGUF In ComfyUI, load the GGUF diffusion file with Unet Loader (GGUF). Load the text encoder with CLIPLoader and set its type to qwen_image; load the VAE with VAELoader. For a Safetensors diffusion file, use UNETLoader instead. If VRAM runs out, start ComfyUI with --lowvram. The README also points to official text-to-image and image-edit workflow templates. Frequently asked questions Q: Can I use Qwen-Image-2.1-Uncensored-Quantized commercially? A: The repository states the Qwen Research License. The provided information does not specify commercial-use permissions, so review the license terms before commercial use. Q: How much VRAM do I need to run it? A: No minimum VRAM requirement is stated. The recommended setup uses a Q4_K_M diffusion file of about 4.6 GB in VRAM and an INT8 text encoder of about 9.35 GB in system RAM; the VAE is 676 MB. Use --lowvram if ComfyUI reports a VRAM out-of-memory error. Q: Which quantization should I choose for ComfyUI? A: The README recommends Q4_K_M as the best balance of GGUF size and quality. It lists Q4_K_M at 4.60 GB, Q5_K_M at 5.22 GB, Q6_K at 5.88 GB, and Q8_0 at 7.59 GB, but does not publish comparative quality or speed measurements. Q: How does it compare with Qwen-Image-2.1-GGUF for uncensored generation? A: This release explicitly has no built-in safety checker or content filter. The similar model’s notice says a fully uncensored version is in development, so this release is the documented choice when uncensored behavior is required now; the supplied information does not establish a quality or speed difference. Q: What are the known image-quality issues? A: The README provides a benchmark image but no numerical results, documented failure modes, or output-resolution details. It recommends Q4_K_M for a GGUF size-quality balance, but does not quantify quality loss across quantizations. Q: Can I fine-tune this model? A: The README documents quantized files for local inference through ComfyUI, not a fine-tuning workflow. It does not specify fine-tuning support or a training framework. Q: How fast is inference, and what batch size should I use? A: The README gives no inference-time, throughput, or batch-size measurements. It says to keep the diffusion model in GPU VRAM because speed matters during sampling, and to run or offload the text encoder to system RAM because it encodes once per prompt. Q: Does the model filter NSFW prompts? A: No. The release has no built-in safety checker or content filter and can generate adult, NSFW, and sensitive imagery without prompt refusals or blacked-out images. Click here to read the full guide to Qwen-Image-2.1-Uncensored-Quantized

  5. Reddit · · r/LocalLLaMA · u/Ok-Director4174 · leejet/stable-diffusion.cpp

    Kokon 0.10: the Qwen-Image 2.1 text encoder now writes your prompts too (no extra model), plus your own LoRAs (beta) Kokon 0.10: Prompt+ and your own LoRAs A week ago I posted Kokon here, a no-settings desktop editor for Qwen-Image 2.1. 0.10 is out with the two things people asked for most. Prompt+. Type a short idea, in any language, and Kokon writes a detailed prompt from it before making the image. For edits it looks at your photo first. You watch the prompt being written, and the result keeps both your words and the written prompt, so you can reuse either. It's off by default, one click next to Quality. Both system prompts are editable in Settings. The prompt is written by Qwen3-VL 8B, which is the text encoder Qwen-Image 2.1 already loads. So there's no second model to download and nothing extra in memory. It adds about 2 s per image on an RTX 5070 Ti and about 13 s on an M2 Pro, and it works on 8 GB cards. Your own LoRAs (beta). Load a Qwen-Image 2.1 LoRA in Settings, set its strength and trigger words, then turn it on per project with one click, up to 3 at once. Kokon checks each file and works on its own copy, so your file isn't changed. LoRAs for older Qwen-Image versions (1.0, 2512, Edit 2509/2511) are refused, because they don't work on 2.1. So far it's tested on Windows with NVIDIA only. If you try it on Mac or Linux, please tell me how it goes. An honest note: I said there would be a curated LoRA list. I tested the popular 2.1 LoRAs on the Turbo model Kokon runs, and today they don't beat what Turbo does with a good prompt. So there's no catalog for now, and it comes when a LoRA earns its place. Under the hood. Kokon now runs its own build of stable-diffusion.cpp on Windows, macOS and Linux. It's upstream plus text generation on the already-loaded text encoder: about 127 tokens/s on a 5070 Ti, the same tokens llama.cpp gives. The image side is upstream's code and makes bit-identical images. Upstream prefers to leave text generation to llama.cpp (#2155), which is fair, so it lives in a fork that I keep close to upstream. Also new: a new look, deleting several projects at once, and fixes for Linux/macOS engine crashes, Windows reserved ports and 8 GB cards. Updating from 0.9.x keeps your images and models. The new engine is a one-time download, 29–352 MB depending on your platform. Free and open source (AGPL), Windows, macOS 15+ and Linux: GitHub · kokon.app Still not there: other models, a server/browser mode for Linux boxes, code signing. (Weights: Qwen Research License, non-commercial.)

    12 points · 21 comments
  6. local llm lightweight, high-performance desktop tools using pure C++ text to image! add llm to to any desktop app leejet/stable-diffusion.cpp

    10 views

Achievements

Awards earned by the repositories leejet owns. Select an award to embed its badge.

Gold
01st place finishes
Silver
02nd place finishes
Bronze
13rd place finishes
Awarded repositories
1Owned by leejet now

Repositories

Ordered by gold, then silver, then bronze.

  1. stable-diffusion.cppBest: 3rd by stars, 299 stars001

Every award

Top-three finishes of these repositories in completed trending days and weeks, newest first.

  1. stable-diffusion.cpp

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.