Upload folder using huggingface_hub
Browse files- Dockerfile.sd-cli-cu12 +109 -0
- Dockerfile.sd-cli-cu13 +86 -0
- LICENSE +15 -0
- NOTICE +6 -0
- README.md +19 -0
- build-and-validate-sd-cli.sh +158 -0
Dockerfile.sd-cli-cu12
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Dockerfile.sd-cli-cu12 β arch-correct multi-arch sd-cli (CUDA 12.8 toolchain)
|
| 2 |
+
# ---------------------------------------------------------------------------
|
| 3 |
+
# WHY THIS EXISTS
|
| 4 |
+
# The prebuilt sd-cli currently shipped at /download/sd-cli-cu12 was compiled
|
| 5 |
+
# on CUDA 12.4 with NO CMAKE_CUDA_ARCHITECTURES, so it emits no sm_120 SASS
|
| 6 |
+
# and throws "no kernel image is available for execution on the device" on
|
| 7 |
+
# Blackwell (RTX 50-series, sm_120) cards. sd-cli powers EVERY sdcpp model
|
| 8 |
+
# (z-image, SD3.5, FLUX.2-klein, HiDream, WAN), so all of them are dead on
|
| 9 |
+
# Blackwell until this fat binary replaces it.
|
| 10 |
+
#
|
| 11 |
+
# WHAT CHANGED vs the golden recipe
|
| 12 |
+
# NOTHING except the architecture list. Same upstream repo, same pinned ref,
|
| 13 |
+
# same feature flags (-DSD_CUDA=ON -DSD_WEBM=ON -DSD_WEBP=ON). The ONLY added
|
| 14 |
+
# flag is -DCMAKE_CUDA_ARCHITECTURES, which makes this a strict SUPERSET of
|
| 15 |
+
# the current binary: it still runs on every card the old one did (Turing,
|
| 16 |
+
# Ampere, Ada, Hopper) AND adds Blackwell (sm_120) + a 120-virtual PTX tail
|
| 17 |
+
# for forward-compat JIT on future archs.
|
| 18 |
+
#
|
| 19 |
+
# ARCH LIST (CUDA 12.8 β broad coverage of older cards)
|
| 20 |
+
# 70-real Volta (V100)
|
| 21 |
+
# 75-real Turing (RTX 20xx, T4, GTX 16xx)
|
| 22 |
+
# 80-real Ampere (A100)
|
| 23 |
+
# 86-real Ampere (RTX 30xx, A10, A40)
|
| 24 |
+
# 89-real Ada (RTX 40xx, L4, L40)
|
| 25 |
+
# 90-real Hopper (H100, H200)
|
| 26 |
+
# 100-real Blackwell DC (B100/B200, GB100)
|
| 27 |
+
# 120-real Blackwell (RTX 50xx, GB202) <-- the whole point
|
| 28 |
+
# 120-virtual PTX tail for compute_120 (JIT forward-compat)
|
| 29 |
+
# The "-real" suffix bakes SASS cubins; "-virtual" bakes PTX. CUDA 12.8 is the
|
| 30 |
+
# first toolkit that supports sm_100 + sm_120, so 12.8.x is the FLOOR for this
|
| 31 |
+
# image β do not downgrade the base.
|
| 32 |
+
#
|
| 33 |
+
# VERIFY THE LIST: the build prints `nvcc --list-gpu-arch` below. If cmake errors
|
| 34 |
+
# with "unsupported gpu architecture", reconcile CUDA_ARCHS against that printout
|
| 35 |
+
# (a listed-but-unsupported arch fails the build β that is the guard, by design).
|
| 36 |
+
#
|
| 37 |
+
# This image is NOT shipped. The operator builds it, extracts /out/sd-cli, and
|
| 38 |
+
# (after Blackwell validation + Ada/Ampere regression) scp's the binary to the
|
| 39 |
+
# VPS. See docs/build/build-and-validate-sd-cli.sh.
|
| 40 |
+
# ---------------------------------------------------------------------------
|
| 41 |
+
|
| 42 |
+
# CUDA 12.8 devel (toolchain + headers). 22.04 base β glibc 2.35 floor, which
|
| 43 |
+
# keeps the extracted binary portable across the varied provider boxes that pull
|
| 44 |
+
# it. Bump the patch tag (12.8.x) only to another tag that exists on Docker Hub.
|
| 45 |
+
# Tag VERIFIED present on Docker Hub 2026-06-11 (nvidia/cuda registry).
|
| 46 |
+
FROM nvidia/cuda:12.8.1-devel-ubuntu22.04
|
| 47 |
+
|
| 48 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 49 |
+
|
| 50 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 51 |
+
git cmake build-essential binutils ca-certificates \
|
| 52 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 53 |
+
|
| 54 |
+
# --- Identical upstream source to the golden recipe ------------------------
|
| 55 |
+
# Repo + ref are LOCKED to what docs/golden-provider-image.md validated. These
|
| 56 |
+
# pin the feature set (--ref-image, --llm_vision, vid_gen, --diffusion-fa) that
|
| 57 |
+
# image-edit + video depend on. DO NOT change the repo or ref to "add arches" β
|
| 58 |
+
# arches are added purely via CMAKE_CUDA_ARCHITECTURES below.
|
| 59 |
+
ARG SDCPP_REPO=https://github.com/leejet/stable-diffusion.cpp
|
| 60 |
+
# Pinned to the leejet release TAG master-656-0e4ee04 (full SHA
|
| 61 |
+
# 0e4ee04488159b81d95a9ffcd983a077fd5dcb77, dated 2026-05-28). A named release
|
| 62 |
+
# tag is preferred over a bare 7-char short hash: immutable, unambiguous as the
|
| 63 |
+
# repo grows, and self-documenting. This is the SAME commit the golden recipe
|
| 64 |
+
# validated β all four required flags (--ref-image, --llm_vision, vid_gen,
|
| 65 |
+
# --diffusion-fa) are registered in examples/common/common.cpp at this ref, so
|
| 66 |
+
# the build carries them. See docs/golden-provider-image.md (SOURCE OF TRUTH).
|
| 67 |
+
ARG SDCPP_REF=master-656-0e4ee04
|
| 68 |
+
|
| 69 |
+
# Broadest set CUDA 12.8 supports, ALWAYS including 120-real + 120-virtual.
|
| 70 |
+
ARG CUDA_ARCHS="70-real;75-real;80-real;86-real;89-real;90-real;100-real;120-real;120-virtual"
|
| 71 |
+
|
| 72 |
+
WORKDIR /opt
|
| 73 |
+
RUN git clone "${SDCPP_REPO}" sdcpp \
|
| 74 |
+
&& cd sdcpp \
|
| 75 |
+
&& git checkout "${SDCPP_REF}" \
|
| 76 |
+
&& git submodule update --init --recursive
|
| 77 |
+
|
| 78 |
+
WORKDIR /opt/sdcpp
|
| 79 |
+
|
| 80 |
+
# Print the toolkit's ground-truth arch list for operator verification. The
|
| 81 |
+
# build log will show this right before configure; cross-check CUDA_ARCHS here.
|
| 82 |
+
RUN echo "=== nvcc --list-gpu-arch (CUDA 12.8) ===" && nvcc --list-gpu-arch && \
|
| 83 |
+
echo "=== CMAKE_CUDA_ARCHITECTURES = ${CUDA_ARCHS} ==="
|
| 84 |
+
|
| 85 |
+
# IDENTICAL cmake flags to the golden recipe + the one functional add:
|
| 86 |
+
# -DCMAKE_CUDA_ARCHITECTURES. ggml (sd.cpp's CUDA backend) honors the standard
|
| 87 |
+
# CMAKE_CUDA_ARCHITECTURES var; if a future ggml bump ignores it, the fallback
|
| 88 |
+
# is -DGGML_CUDA_ARCHITECTURES with the same value.
|
| 89 |
+
RUN cmake -B build \
|
| 90 |
+
-DCMAKE_BUILD_TYPE=Release \
|
| 91 |
+
-DSD_CUDA=ON -DSD_WEBM=ON -DSD_WEBP=ON \
|
| 92 |
+
-DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHS}" \
|
| 93 |
+
&& cmake --build build --config Release --target sd-cli -j"$(nproc)"
|
| 94 |
+
|
| 95 |
+
# Park the binary at a known path for `docker create` + `docker cp` extraction.
|
| 96 |
+
RUN mkdir -p /out \
|
| 97 |
+
&& cp "$(find build -name sd-cli -type f -perm -u+x | head -n1)" /out/sd-cli \
|
| 98 |
+
&& chmod 755 /out/sd-cli \
|
| 99 |
+
&& echo "sd-cli (cu12 fat binary) staged at /out/sd-cli"
|
| 100 |
+
|
| 101 |
+
# Flag sanity β GPU-FREE. Do NOT run the binary here. The docker BUILD sandbox has
|
| 102 |
+
# no GPU: libcuda is only present at `docker run --gpus`, so `/out/sd-cli --help`
|
| 103 |
+
# can fail to init the CUDA backend and error out BEFORE printing its flags β which
|
| 104 |
+
# would falsely trip "missing flags" on a perfectly good build. Instead, confirm the
|
| 105 |
+
# flag literals are baked into the binary's string table; `strings` needs no CUDA.
|
| 106 |
+
# The real runtime check (--help + a generation) runs WITH the GPU in
|
| 107 |
+
# build-and-validate-sd-cli.sh, the only place the binary can actually execute.
|
| 108 |
+
RUN strings /out/sd-cli | grep -E -- '--ref-image|--llm_vision|vid_gen|--diffusion-fa' \
|
| 109 |
+
|| (echo "BUILD MISSING REQUIRED FLAG LITERALS β wrong ref?" && exit 1)
|
Dockerfile.sd-cli-cu13
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Dockerfile.sd-cli-cu13 β arch-correct multi-arch sd-cli (CUDA 13 toolchain)
|
| 2 |
+
# ---------------------------------------------------------------------------
|
| 3 |
+
# Companion to Dockerfile.sd-cli-cu12. Same upstream repo + ref + feature flags;
|
| 4 |
+
# the ONLY difference between the two images is the CUDA toolkit and therefore
|
| 5 |
+
# the architecture list. See Dockerfile.sd-cli-cu12 for the full "why".
|
| 6 |
+
#
|
| 7 |
+
# WHY A SEPARATE CUDA 13 IMAGE
|
| 8 |
+
# setup.py picks the prebuilt by driver: `cu13` when the host CUDA major >= 13,
|
| 9 |
+
# else `cu12` (downloads/setup.py fetch_or_build_sdcli). A binary built against
|
| 10 |
+
# the CUDA 13 runtime needs the CUDA 13 toolchain. Blackwell boxes on a CUDA 13
|
| 11 |
+
# driver pull THIS one.
|
| 12 |
+
#
|
| 13 |
+
# CUDA 13 RAISED ITS ARCH FLOOR β the lists differ BY DESIGN.
|
| 14 |
+
# CUDA 13 dropped the older virtual/real arches (Maxwell sm_50/52/53, Pascal
|
| 15 |
+
# sm_60/61/62, and Volta sm_70). Its supported floor is Turing sm_75. So the
|
| 16 |
+
# cu13 list starts at 75-real (NOT 70-real like cu12) and runs up through 120:
|
| 17 |
+
# 75-real Turing (RTX 20xx, T4)
|
| 18 |
+
# 80-real Ampere (A100)
|
| 19 |
+
# 86-real Ampere (RTX 30xx, A10, A40)
|
| 20 |
+
# 89-real Ada (RTX 40xx, L4, L40)
|
| 21 |
+
# 90-real Hopper (H100, H200)
|
| 22 |
+
# 100-real Blackwell DC (B100/B200)
|
| 23 |
+
# 120-real Blackwell (RTX 50xx) <-- the whole point
|
| 24 |
+
# 120-virtual PTX tail for compute_120 (JIT forward-compat)
|
| 25 |
+
# Putting 70-real here would FAIL the build (sm_70 unsupported in CUDA 13) β
|
| 26 |
+
# that is the intended divergence, not an omission. Volta/Pascal/Maxwell users
|
| 27 |
+
# stay on the cu12 binary, which setup.py already routes them to.
|
| 28 |
+
#
|
| 29 |
+
# VERIFY: the build prints `nvcc --list-gpu-arch` (CUDA 13) below. If cmake errors
|
| 30 |
+
# on an unsupported arch, reconcile CUDA_ARCHS against that printout.
|
| 31 |
+
# ---------------------------------------------------------------------------
|
| 32 |
+
|
| 33 |
+
# CUDA 13 devel. Keep ubuntu22.04 (glibc 2.35) for binary portability, matching
|
| 34 |
+
# the cu12 image. VERIFIED 2026-06-11: nvidia/cuda:13.0.1-devel-ubuntu22.04 DOES
|
| 35 |
+
# exist on Docker Hub, so cu13 stays on 22.04 / glibc 2.35 β NO elevated glibc
|
| 36 |
+
# floor vs cu12. (13.0.1-devel-ubuntu24.04 also exists; only fall back to it if a
|
| 37 |
+
# future 13.x drops the 22.04 variant β that would raise the binary's floor to
|
| 38 |
+
# glibc 2.39 on provider boxes, so note it on swap if you ever do.)
|
| 39 |
+
FROM nvidia/cuda:13.0.1-devel-ubuntu22.04
|
| 40 |
+
|
| 41 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 42 |
+
|
| 43 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 44 |
+
git cmake build-essential binutils ca-certificates \
|
| 45 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 46 |
+
|
| 47 |
+
# Same locked upstream as the golden recipe and the cu12 image. Pinned to the
|
| 48 |
+
# leejet release TAG master-656-0e4ee04 (full SHA
|
| 49 |
+
# 0e4ee04488159b81d95a9ffcd983a077fd5dcb77, dated 2026-05-28) β a named tag,
|
| 50 |
+
# not a bare short hash. All four required flags (--ref-image, --llm_vision,
|
| 51 |
+
# vid_gen, --diffusion-fa) are present in examples/common/common.cpp at this ref.
|
| 52 |
+
ARG SDCPP_REPO=https://github.com/leejet/stable-diffusion.cpp
|
| 53 |
+
ARG SDCPP_REF=master-656-0e4ee04
|
| 54 |
+
|
| 55 |
+
# Broadest set CUDA 13 supports (floor = sm_75), ALWAYS including 120-real +
|
| 56 |
+
# 120-virtual. NOTE the absence of 70-real vs the cu12 list β intentional.
|
| 57 |
+
ARG CUDA_ARCHS="75-real;80-real;86-real;89-real;90-real;100-real;120-real;120-virtual"
|
| 58 |
+
|
| 59 |
+
WORKDIR /opt
|
| 60 |
+
RUN git clone "${SDCPP_REPO}" sdcpp \
|
| 61 |
+
&& cd sdcpp \
|
| 62 |
+
&& git checkout "${SDCPP_REF}" \
|
| 63 |
+
&& git submodule update --init --recursive
|
| 64 |
+
|
| 65 |
+
WORKDIR /opt/sdcpp
|
| 66 |
+
|
| 67 |
+
RUN echo "=== nvcc --list-gpu-arch (CUDA 13) ===" && nvcc --list-gpu-arch && \
|
| 68 |
+
echo "=== CMAKE_CUDA_ARCHITECTURES = ${CUDA_ARCHS} ==="
|
| 69 |
+
|
| 70 |
+
RUN cmake -B build \
|
| 71 |
+
-DCMAKE_BUILD_TYPE=Release \
|
| 72 |
+
-DSD_CUDA=ON -DSD_WEBM=ON -DSD_WEBP=ON \
|
| 73 |
+
-DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHS}" \
|
| 74 |
+
&& cmake --build build --config Release --target sd-cli -j"$(nproc)"
|
| 75 |
+
|
| 76 |
+
RUN mkdir -p /out \
|
| 77 |
+
&& cp "$(find build -name sd-cli -type f -perm -u+x | head -n1)" /out/sd-cli \
|
| 78 |
+
&& chmod 755 /out/sd-cli \
|
| 79 |
+
&& echo "sd-cli (cu13 fat binary) staged at /out/sd-cli"
|
| 80 |
+
|
| 81 |
+
# Flag sanity β GPU-FREE (see Dockerfile.sd-cli-cu12 for the full why). The build
|
| 82 |
+
# sandbox has no GPU, so running `/out/sd-cli --help` can error before printing and
|
| 83 |
+
# falsely report "missing flags". Check the binary's string table instead β no CUDA
|
| 84 |
+
# needed. The real runtime check runs WITH the GPU in build-and-validate-sd-cli.sh.
|
| 85 |
+
RUN strings /out/sd-cli | grep -E -- '--ref-image|--llm_vision|vid_gen|--diffusion-fa' \
|
| 86 |
+
|| (echo "BUILD MISSING REQUIRED FLAG LITERALS β wrong ref?" && exit 1)
|
LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License β build recipe Β© 2026 DEcntAI
|
| 2 |
+
|
| 3 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 4 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 5 |
+
in the Software without restriction, including without limitation the rights
|
| 6 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 7 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 8 |
+
furnished to do so, subject to the following conditions:
|
| 9 |
+
|
| 10 |
+
The above copyright notice and this permission notice shall be included in all
|
| 11 |
+
copies or substantial portions of the Software.
|
| 12 |
+
|
| 13 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 14 |
+
IMPLIED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
| 15 |
+
OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
|
NOTICE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Prebuilt sd-cli binaries (in Releases) are compiled from:
|
| 2 |
+
stable-diffusion.cpp - https://github.com/leejet/stable-diffusion.cpp (MIT)
|
| 3 |
+
ggml - https://github.com/ggml-org/ggml (MIT)
|
| 4 |
+
built at ref master-656-0e4ee04. Credit for the inference engine goes to
|
| 5 |
+
leejet and the ggml authors. This repo adds only a multi-arch build recipe
|
| 6 |
+
(CUDA 12/13, sm_70 through sm_120 incl. Blackwell).
|
README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# sd-cli - multi-arch stable-diffusion.cpp builds (incl. Blackwell)
|
| 2 |
+
|
| 3 |
+
Prebuilt `sd-cli` binaries from leejet/stable-diffusion.cpp @ `master-656-0e4ee04`,
|
| 4 |
+
plus the build recipe. Two CUDA variants, both carrying `sm_120` (Blackwell):
|
| 5 |
+
|
| 6 |
+
| binary | toolkit | arches (real + PTX) | driver floor |
|
| 7 |
+
|---------------|---------|--------------------------------------|---------------|
|
| 8 |
+
| `sd-cli-cu12` | 12.8 | 70 75 80 86 89 90 100 120 (+120 PTX) | sm_70 (Volta) |
|
| 9 |
+
| `sd-cli-cu13` | 13.0 | 75 80 86 89 90 100 120 (+120 PTX) | sm_75 (Turing)|
|
| 10 |
+
|
| 11 |
+
Download from **Releases**. Dynamically linked against the CUDA runtime
|
| 12 |
+
(cudart/cublas/nccl) - same as upstream - so run on a box where those are on
|
| 13 |
+
the loader path (a PyTorch/CUDA image, or `pip install nvidia-cuda-runtime-cu12
|
| 14 |
+
nvidia-cublas-cu12 nvidia-nccl-cu12` + LD_LIBRARY_PATH). Build it yourself via
|
| 15 |
+
the included Dockerfiles + `build-and-validate-sd-cli.sh`.
|
| 16 |
+
|
| 17 |
+
## License
|
| 18 |
+
Build recipe: MIT (see LICENSE). Binaries derive from stable-diffusion.cpp and
|
| 19 |
+
ggml, both MIT - see NOTICE.
|
build-and-validate-sd-cli.sh
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# build-and-validate-sd-cli.sh
|
| 3 |
+
# ===========================================================================
|
| 4 |
+
# OPERATOR script. Run this ON A REAL BLACKWELL (RTX 50-series, sm_120) NODE
|
| 5 |
+
# that has Docker + the NVIDIA container toolkit. It:
|
| 6 |
+
# 1. Builds BOTH arch-correct sd-cli images (cu12 + cu13).
|
| 7 |
+
# 2. Extracts BOTH binaries to ./dist/ locally (no container left running).
|
| 8 |
+
# 3. Runs a REAL generation with the arch-matching binary against a small
|
| 9 |
+
# sdcpp model and greps the output for "no kernel image" / failure.
|
| 10 |
+
# (NOT `--help` β that never loads a CUDA kernel and would falsely pass.)
|
| 11 |
+
# 4. PRINTS (does NOT perform) the final scp to the VPS downloads/ dir, plus
|
| 12 |
+
# the Ada/Ampere regression-test reminder.
|
| 13 |
+
#
|
| 14 |
+
# This script never scp's, never touches the live /download/sd-cli-* binaries,
|
| 15 |
+
# and never runs on the VPS. It builds + validates only. The live swap is a
|
| 16 |
+
# deliberate, separate, manual step you perform AFTER the checks below pass.
|
| 17 |
+
#
|
| 18 |
+
# DISK NOTE: the CUDA *-devel base images are several GB each; both builds plus
|
| 19 |
+
# layers can exceed ~30 GB. Point Docker's data-root at a big volume first, e.g.
|
| 20 |
+
# sudo mkdir -p /mnt/big/docker
|
| 21 |
+
# echo '{"data-root":"/mnt/big/docker"}' | sudo tee /etc/docker/daemon.json
|
| 22 |
+
# sudo systemctl restart docker
|
| 23 |
+
# ===========================================================================
|
| 24 |
+
set -uo pipefail
|
| 25 |
+
|
| 26 |
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
| 27 |
+
DIST="${HERE}/dist"
|
| 28 |
+
mkdir -p "${DIST}"
|
| 29 |
+
|
| 30 |
+
# --- Tunables (override via env) -------------------------------------------
|
| 31 |
+
# A small sdcpp model + a real generation command. sd-cli MUST actually load a
|
| 32 |
+
# CUDA kernel for this to prove sm_120 works, so point MODEL at a small checkpoint
|
| 33 |
+
# already on this box (e.g. an SD1.5 / z-image GGUF). Adjust GEN_ARGS to whatever
|
| 34 |
+
# minimal valid invocation your model needs.
|
| 35 |
+
MODEL="${MODEL:-/workspace/models/sd-v1-5.safetensors}"
|
| 36 |
+
GEN_PROMPT="${GEN_PROMPT:-a red apple on a table}"
|
| 37 |
+
GEN_OUT="${GEN_OUT:-${DIST}/_validate_out.png}"
|
| 38 |
+
# Keep it tiny + fast: small res, few steps. Override if your model needs more.
|
| 39 |
+
GEN_ARGS="${GEN_ARGS:---steps 4 -W 256 -H 256 --cfg-scale 1.0}"
|
| 40 |
+
|
| 41 |
+
VPS_USER="${VPS_USER:-youruser}"
|
| 42 |
+
VPS_HOST="${VPS_HOST:-your.server.example}"
|
| 43 |
+
VPS_DLDIR="${VPS_DLDIR:-/path/to/your/downloads}"
|
| 44 |
+
|
| 45 |
+
CU12_IMG="decntai/sd-cli-build:cu12"
|
| 46 |
+
CU13_IMG="decntai/sd-cli-build:cu13"
|
| 47 |
+
|
| 48 |
+
say() { printf '\n\033[1;36m== %s ==\033[0m\n' "$*"; }
|
| 49 |
+
warn() { printf '\033[1;33m%s\033[0m\n' "$*"; }
|
| 50 |
+
die() { printf '\033[1;31mFATAL: %s\033[0m\n' "$*" >&2; exit 1; }
|
| 51 |
+
|
| 52 |
+
command -v docker >/dev/null || die "docker not found"
|
| 53 |
+
command -v nvidia-smi >/dev/null || warn "nvidia-smi not found β is this a GPU box?"
|
| 54 |
+
|
| 55 |
+
# --- 1. Build both images --------------------------------------------------
|
| 56 |
+
say "Building cu12 image (${CU12_IMG})"
|
| 57 |
+
docker build -f "${HERE}/Dockerfile.sd-cli-cu12" -t "${CU12_IMG}" "${HERE}" \
|
| 58 |
+
|| die "cu12 build failed (check the nvcc --list-gpu-arch printout vs CUDA_ARCHS)"
|
| 59 |
+
|
| 60 |
+
say "Building cu13 image (${CU13_IMG})"
|
| 61 |
+
docker build -f "${HERE}/Dockerfile.sd-cli-cu13" -t "${CU13_IMG}" "${HERE}" \
|
| 62 |
+
|| die "cu13 build failed (check the nvcc --list-gpu-arch printout vs CUDA_ARCHS)"
|
| 63 |
+
|
| 64 |
+
# --- 2. Extract both binaries to ./dist ------------------------------------
|
| 65 |
+
extract() { # $1=image $2=dest
|
| 66 |
+
local cid
|
| 67 |
+
cid="$(docker create "$1")" || die "docker create $1 failed"
|
| 68 |
+
docker cp "${cid}:/out/sd-cli" "$2" || { docker rm -f "${cid}" >/dev/null; die "cp from $1 failed"; }
|
| 69 |
+
docker rm -f "${cid}" >/dev/null
|
| 70 |
+
chmod 755 "$2"
|
| 71 |
+
printf ' extracted %s (%s MB)\n' "$2" "$(( $(stat -c%s "$2") / 1024 / 1024 ))"
|
| 72 |
+
}
|
| 73 |
+
say "Extracting binaries to ${DIST}"
|
| 74 |
+
extract "${CU12_IMG}" "${DIST}/sd-cli-cu12"
|
| 75 |
+
extract "${CU13_IMG}" "${DIST}/sd-cli-cu13"
|
| 76 |
+
|
| 77 |
+
# --- 3. REAL generation with the arch-matching binary ----------------------
|
| 78 |
+
# Pick the binary by host CUDA major (mirrors setup.py's fetch logic).
|
| 79 |
+
CUDA_MAJOR="$(nvidia-smi --query-gpu=driver_version --format=csv,noheader 2>/dev/null | head -n1 | cut -d. -f1)"
|
| 80 |
+
# driver_version major != CUDA major; the reliable signal is `nvcc` if present,
|
| 81 |
+
# else fall back to the CUDA runtime reported by nvidia-smi.
|
| 82 |
+
if command -v nvcc >/dev/null; then
|
| 83 |
+
TK_MAJOR="$(nvcc --version | grep -oE 'release [0-9]+' | grep -oE '[0-9]+' | head -n1)"
|
| 84 |
+
else
|
| 85 |
+
TK_MAJOR="$(nvidia-smi | grep -oE 'CUDA Version: [0-9]+' | grep -oE '[0-9]+' | head -n1)"
|
| 86 |
+
fi
|
| 87 |
+
TK_MAJOR="${TK_MAJOR:-12}"
|
| 88 |
+
if [ "${TK_MAJOR}" -ge 13 ]; then
|
| 89 |
+
VAL_BIN="${DIST}/sd-cli-cu13"; VAL_ARCH="cu13"
|
| 90 |
+
else
|
| 91 |
+
VAL_BIN="${DIST}/sd-cli-cu12"; VAL_ARCH="cu12"
|
| 92 |
+
fi
|
| 93 |
+
|
| 94 |
+
# --- 3a. Runtime flag check (functional β moved OUT of the Dockerfiles) -------
|
| 95 |
+
# THIS is the right place to run the binary: this is a GPU box (libcuda present),
|
| 96 |
+
# unlike the docker BUILD sandbox where `--help` can fail to init CUDA and error
|
| 97 |
+
# before printing. The Dockerfiles only do a GPU-free `strings` smoke; here we
|
| 98 |
+
# assert all four required flags actually surface in --help on real hardware.
|
| 99 |
+
say "Runtime flag check: ${VAL_ARCH} --help must list all four required flags"
|
| 100 |
+
HELP_OUT="$("${VAL_BIN}" --help 2>&1 || true)"
|
| 101 |
+
for f in '--ref-image' '--llm_vision' 'vid_gen' '--diffusion-fa'; do
|
| 102 |
+
echo "${HELP_OUT}" | grep -qF -- "$f" \
|
| 103 |
+
|| die "Required flag '$f' absent from ${VAL_ARCH} --help β wrong/old ref? Do NOT ship."
|
| 104 |
+
done
|
| 105 |
+
say "All four required flags present in ${VAL_ARCH} --help"
|
| 106 |
+
|
| 107 |
+
say "Validating ${VAL_ARCH} binary on THIS GPU with a real generation"
|
| 108 |
+
if [ ! -f "${MODEL}" ]; then
|
| 109 |
+
warn "MODEL not found at ${MODEL}."
|
| 110 |
+
warn "Set MODEL=/path/to/a/small/sdcpp/checkpoint and re-run. CANNOT validate"
|
| 111 |
+
warn "sm_120 without loading a real CUDA kernel β skipping gen, build NOT proven."
|
| 112 |
+
exit 2
|
| 113 |
+
fi
|
| 114 |
+
|
| 115 |
+
rm -f "${GEN_OUT}"
|
| 116 |
+
GEN_LOG="${DIST}/_validate_${VAL_ARCH}.log"
|
| 117 |
+
# shellcheck disable=SC2086
|
| 118 |
+
"${VAL_BIN}" -m "${MODEL}" -p "${GEN_PROMPT}" -o "${GEN_OUT}" ${GEN_ARGS} \
|
| 119 |
+
> "${GEN_LOG}" 2>&1
|
| 120 |
+
GEN_RC=$?
|
| 121 |
+
|
| 122 |
+
echo " exit=${GEN_RC} log=${GEN_LOG}"
|
| 123 |
+
if grep -qiE 'no kernel image|invalid device function|CUDA error|out of memory|failed' "${GEN_LOG}"; then
|
| 124 |
+
warn "---- offending log lines ----"
|
| 125 |
+
grep -niE 'no kernel image|invalid device function|CUDA error|out of memory|failed' "${GEN_LOG}" | sed 's/^/ /'
|
| 126 |
+
die "Generation reported a CUDA/kernel failure on sm_120 β the fat binary is NOT good. Do NOT ship."
|
| 127 |
+
fi
|
| 128 |
+
if [ "${GEN_RC}" -ne 0 ] || [ ! -s "${GEN_OUT}" ]; then
|
| 129 |
+
die "Generation exited ${GEN_RC} or produced no output (${GEN_OUT}). Do NOT ship."
|
| 130 |
+
fi
|
| 131 |
+
say "VALIDATION PASSED on Blackwell (${VAL_ARCH}) β real image written to ${GEN_OUT}"
|
| 132 |
+
|
| 133 |
+
# --- 4. Next steps: PRINT ONLY (no scp performed here) ---------------------
|
| 134 |
+
cat <<EOF
|
| 135 |
+
|
| 136 |
+
============================================================================
|
| 137 |
+
NEXT STEPS β performed MANUALLY by you, NOT by this script
|
| 138 |
+
============================================================================
|
| 139 |
+
1) REGRESSION TEST FIRST. Before any live swap, run the SAME real generation
|
| 140 |
+
with the matching binary on an Ada (sm_89, e.g. RTX 4060) AND an Ampere
|
| 141 |
+
(sm_86, e.g. RTX 3060) box. The fat binary MUST still work there β it is a
|
| 142 |
+
strict superset, not a replacement. If either regresses, do NOT ship.
|
| 143 |
+
|
| 144 |
+
2) Only after Blackwell PASS + Ada/Ampere regression PASS, copy the binaries
|
| 145 |
+
to the VPS (this script does NOT do this for you):
|
| 146 |
+
|
| 147 |
+
scp ${DIST}/sd-cli-cu12 ${VPS_USER}@${VPS_HOST}:${VPS_DLDIR}/sd-cli-cu12
|
| 148 |
+
scp ${DIST}/sd-cli-cu13 ${VPS_USER}@${VPS_HOST}:${VPS_DLDIR}/sd-cli-cu13
|
| 149 |
+
ssh ${VPS_USER}@${VPS_HOST} 'chmod 755 ${VPS_DLDIR}/sd-cli-cu12 ${VPS_DLDIR}/sd-cli-cu13'
|
| 150 |
+
|
| 151 |
+
3) Confirm they serve:
|
| 152 |
+
curl -sI https://ai.decntai.com/download/sd-cli-cu12 # expect 200
|
| 153 |
+
curl -sI https://ai.decntai.com/download/sd-cli-cu13 # expect 200
|
| 154 |
+
|
| 155 |
+
New providers fetch these via setup.py fetch_or_build_sdcli (cu13 when host
|
| 156 |
+
CUDA major >= 13, else cu12). Existing providers re-run setup.py / re-fetch.
|
| 157 |
+
============================================================================
|
| 158 |
+
EOF
|