From 812230140868f3275a7602af609a895d91924a03 Mon Sep 17 00:00:00 2001 From: Richard Palethorpe Date: Tue, 22 Jul 2025 10:08:51 +0100 Subject: [PATCH 1/3] sync(stablediffusion-cpp): Switch back to upstream and update Signed-off-by: Richard Palethorpe --- .github/workflows/bump_deps.yaml | 2 +- backend/go/stablediffusion-ggml/Makefile | 17 ++-- backend/go/stablediffusion-ggml/gosd.cpp | 121 ++++++++++++++--------- 3 files changed, 80 insertions(+), 60 deletions(-) diff --git a/.github/workflows/bump_deps.yaml b/.github/workflows/bump_deps.yaml index f15d62f7f520..2b7941112c55 100644 --- a/.github/workflows/bump_deps.yaml +++ b/.github/workflows/bump_deps.yaml @@ -21,7 +21,7 @@ jobs: variable: "BARKCPP_VERSION" branch: "main" file: "Makefile" - - repository: "richiejp/stable-diffusion.cpp" + - repository: "leejet/stable-diffusion.cpp" variable: "STABLEDIFFUSION_GGML_VERSION" branch: "master" file: "backend/go/stablediffusion-ggml/Makefile" diff --git a/backend/go/stablediffusion-ggml/Makefile b/backend/go/stablediffusion-ggml/Makefile index 9f15d55118ae..3d3e1427965e 100644 --- a/backend/go/stablediffusion-ggml/Makefile +++ b/backend/go/stablediffusion-ggml/Makefile @@ -18,8 +18,8 @@ GO_TAGS?= LD_FLAGS?= # stablediffusion.cpp (ggml) -STABLEDIFFUSION_GGML_REPO?=https://github.com/richiejp/stable-diffusion.cpp -STABLEDIFFUSION_GGML_VERSION?=10c6501bd05a697e014f1bee3a84e5664290c489 +STABLEDIFFUSION_GGML_REPO?=https://github.com/leejet/stable-diffusion.cpp +STABLEDIFFUSION_GGML_VERSION?=1896b28ef2fd5b3643120e66979bea487385439f # Disable Shared libs as we are linking on static gRPC and we can't mix shared and static CMAKE_ARGS+=-DBUILD_SHARED_LIBS=OFF @@ -91,23 +91,18 @@ endif # (ggml can have different backends cpu, cuda, etc., each backend generates a .a archive) GGML_ARCHIVE_DIR := build/ggml/src/ ALL_ARCHIVES := $(shell find $(GGML_ARCHIVE_DIR) -type f -name '*.a') +ALL_OBJS := $(shell find $(GGML_ARCHIVE_DIR) -type f -name '*.o') # Name of the single merged library COMBINED_LIB := libggmlall.a -# Rule to merge all the .a files into one +# Instead of using the archives generated by GGML, use the object files directly to avoid overwriting objects with the same base name $(COMBINED_LIB): $(ALL_ARCHIVES) - @echo "Merging all .a into $(COMBINED_LIB)" + @echo "Merging all .o into $(COMBINED_LIB): $(ALL_OBJS)" rm -f $@ - mkdir -p merge-tmp - for a in $(ALL_ARCHIVES); do \ - ( cd merge-tmp && ar x ../$$a ); \ - done - ( cd merge-tmp && ar rcs ../$@ *.o ) + ar -qc $@ $(ALL_OBJS) # Ensure we have a proper index ranlib $@ - # Clean up - rm -rf merge-tmp build/libstable-diffusion.a: @echo "Building SD with $(BUILD_TYPE) build type and $(CMAKE_ARGS)" diff --git a/backend/go/stablediffusion-ggml/gosd.cpp b/backend/go/stablediffusion-ggml/gosd.cpp index 4c7c161a69fd..7838c562ab15 100644 --- a/backend/go/stablediffusion-ggml/gosd.cpp +++ b/backend/go/stablediffusion-ggml/gosd.cpp @@ -53,9 +53,43 @@ sd_ctx_t* sd_c; sample_method_t sample_method; +// Copied from the upstream CLI +void sd_log_cb(enum sd_log_level_t level, const char* log, void* data) { + //SDParams* params = (SDParams*)data; + const char* level_str; + + if (!log /*|| (!params->verbose && level <= SD_LOG_DEBUG)*/) { + return; + } + + switch (level) { + case SD_LOG_DEBUG: + level_str = "DEBUG"; + break; + case SD_LOG_INFO: + level_str = "INFO"; + break; + case SD_LOG_WARN: + level_str = "WARN"; + break; + case SD_LOG_ERROR: + level_str = "ERROR"; + break; + default: /* Potential future-proofing */ + level_str = "?????"; + break; + } + + fprintf(stderr, "[%-5s] ", level_str); + fputs(log, stderr); + fflush(stderr); +} + int load_model(char *model, char* options[], int threads, int diff) { fprintf (stderr, "Loading model!\n"); + sd_set_log_callback(sd_log_cb, NULL); + char *stableDiffusionModel = ""; if (diff == 1 ) { stableDiffusionModel = model; @@ -99,7 +133,7 @@ int load_model(char *model, char* options[], int threads, int diff) { } int sample_method_found = -1; - for (int m = 0; m < N_SAMPLE_METHODS; m++) { + for (int m = 0; m < SAMPLE_METHOD_COUNT; m++) { if (!strcmp(sampler, sample_method_str[m])) { sample_method_found = m; } @@ -111,7 +145,7 @@ int load_model(char *model, char* options[], int threads, int diff) { sample_method = (sample_method_t)sample_method_found; int schedule_found = -1; - for (int d = 0; d < N_SCHEDULES; d++) { + for (int d = 0; d < SCHEDULE_COUNT; d++) { if (!strcmp(scheduler, schedule_str[d])) { schedule_found = d; fprintf (stderr, "Found scheduler: %s\n", scheduler); @@ -125,30 +159,28 @@ int load_model(char *model, char* options[], int threads, int diff) { } schedule_t schedule = (schedule_t)schedule_found; - + fprintf (stderr, "Creating context\n"); - sd_ctx_t* sd_ctx = new_sd_ctx(model, - clip_l_path, - clip_g_path, - t5xxl_path, - stableDiffusionModel, - vae_path, - "", - "", - "", - "", - "", - false, - false, - false, - threads, - SD_TYPE_COUNT, - STD_DEFAULT_RNG, - schedule, - false, - false, - false, - false); + sd_ctx_params_t ctx_params; + sd_ctx_params_init(&ctx_params); + ctx_params.model_path = model; + ctx_params.clip_l_path = clip_l_path; + ctx_params.clip_g_path = clip_g_path; + ctx_params.t5xxl_path = t5xxl_path; + ctx_params.diffusion_model_path = stableDiffusionModel; + ctx_params.vae_path = vae_path; + ctx_params.taesd_path = ""; + ctx_params.control_net_path = ""; + ctx_params.lora_model_dir = ""; + ctx_params.embedding_dir = ""; + ctx_params.stacked_id_embed_dir = ""; + ctx_params.vae_decode_only = false; + ctx_params.vae_tiling = false; + ctx_params.free_params_immediately = false; + ctx_params.n_threads = threads; + ctx_params.rng_type = STD_DEFAULT_RNG; + ctx_params.schedule = schedule; + sd_ctx_t* sd_ctx = new_sd_ctx(&ctx_params); if (sd_ctx == NULL) { fprintf (stderr, "failed loading model (generic error)\n"); @@ -169,29 +201,22 @@ int gen_image(char *text, char *negativeText, int width, int height, int steps, fprintf (stderr, "Generating image\n"); - results = txt2img(sd_c, - text, - negativeText, - -1, //clip_skip - cfg_scale, // sfg_scale - 3.5f, - 0, // eta - width, - height, - sample_method, - steps, - seed, - 1, - NULL, - 0.9f, - 20.f, - false, - "", - skip_layers.data(), - skip_layers.size(), - 0, - 0.01, - 0.2); + sd_img_gen_params_t p; + sd_img_gen_params_init(&p); + + p.prompt = text; + p.negative_prompt = negativeText; + p.guidance.txt_cfg = cfg_scale; + p.guidance.slg.layers = skip_layers.data(); + p.guidance.slg.layer_count = skip_layers.size(); + p.width = width; + p.height = height; + p.sample_method = sample_method; + p.sample_steps = steps; + p.seed = seed; + p.input_id_images_path = ""; + + results = generate_image(sd_c, &p); if (results == NULL) { fprintf (stderr, "NO results\n"); From 143423f7bdbd8081e70f26bdba0541cbca4336eb Mon Sep 17 00:00:00 2001 From: Richard Palethorpe Date: Tue, 22 Jul 2025 21:21:10 +0100 Subject: [PATCH 2/3] fix(stablediffusion-ggml): NULL terminate options array to prevent segfault Signed-off-by: Richard Palethorpe --- backend/go/stablediffusion-ggml/gosd.cpp | 5 +++++ backend/go/stablediffusion-ggml/gosd.go | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/go/stablediffusion-ggml/gosd.cpp b/backend/go/stablediffusion-ggml/gosd.cpp index 7838c562ab15..e3e665d7a866 100644 --- a/backend/go/stablediffusion-ggml/gosd.cpp +++ b/backend/go/stablediffusion-ggml/gosd.cpp @@ -104,6 +104,8 @@ int load_model(char *model, char* options[], int threads, int diff) { char *scheduler = ""; char *sampler = ""; + fprintf(stderr, "parsing options\n"); + // If options is not NULL, parse options for (int i = 0; options[i] != NULL; i++) { char *optname = strtok(options[i], ":"); @@ -132,10 +134,13 @@ int load_model(char *model, char* options[], int threads, int diff) { } } + fprintf(stderr, "parsed options\n"); + int sample_method_found = -1; for (int m = 0; m < SAMPLE_METHOD_COUNT; m++) { if (!strcmp(sampler, sample_method_str[m])) { sample_method_found = m; + fprintf(stderr, "Found sampler: %s\n", sampler); } } if (sample_method_found == -1) { diff --git a/backend/go/stablediffusion-ggml/gosd.go b/backend/go/stablediffusion-ggml/gosd.go index 7d8d770ffcf2..fa4d0e72e819 100644 --- a/backend/go/stablediffusion-ggml/gosd.go +++ b/backend/go/stablediffusion-ggml/gosd.go @@ -37,8 +37,8 @@ func (sd *SDGGML) Load(opts *pb.ModelOptions) error { size := C.size_t(unsafe.Sizeof((*C.char)(nil))) length := C.size_t(len(opts.Options)) - options = (**C.char)(C.malloc(length * size)) - view := (*[1 << 30]*C.char)(unsafe.Pointer(options))[0:len(opts.Options):len(opts.Options)] + options = (**C.char)(C.malloc((length + 1) * size)) + view := (*[1 << 30]*C.char)(unsafe.Pointer(options))[0:len(opts.Options) + 1:len(opts.Options) + 1] var diffusionModel int @@ -66,6 +66,7 @@ func (sd *SDGGML) Load(opts *pb.ModelOptions) error { for i, x := range oo { view[i] = C.CString(x) } + view[len(oo)] = nil sd.cfgScale = opts.CFGScale From 5e0c84582a8bc21fa744f069fc095b0727b24132 Mon Sep 17 00:00:00 2001 From: Richard Palethorpe Date: Wed, 23 Jul 2025 16:29:47 +0100 Subject: [PATCH 3/3] fix(build): Add BUILD_TYPE and BASE_IMAGE to all backends Signed-off-by: Richard Palethorpe --- Makefile | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 0baefa28329d..ec2c28e6dda1 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,7 @@ backends/stablediffusion-ggml: docker-build-stablediffusion-ggml docker-save-sta backends/whisper: docker-build-whisper docker-save-whisper build ./local-ai backends install "ocifile://$(abspath ./backend-images/whisper.tar)" - + backends/silero-vad: docker-build-silero-vad docker-save-silero-vad build ./local-ai backends install "ocifile://$(abspath ./backend-images/silero-vad.tar)" @@ -449,19 +449,19 @@ backend-images: mkdir -p backend-images docker-build-llama-cpp: - docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg IMAGE_BASE=$(IMAGE_BASE) -t local-ai-backend:llama-cpp -f backend/Dockerfile.llama-cpp . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:llama-cpp -f backend/Dockerfile.llama-cpp . docker-build-bark-cpp: - docker build -t local-ai-backend:bark-cpp -f backend/Dockerfile.golang --build-arg BACKEND=bark-cpp . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:bark-cpp -f backend/Dockerfile.golang --build-arg BACKEND=bark-cpp . docker-build-piper: - docker build -t local-ai-backend:piper -f backend/Dockerfile.golang --build-arg BACKEND=piper . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:piper -f backend/Dockerfile.golang --build-arg BACKEND=piper . docker-build-local-store: - docker build -t local-ai-backend:local-store -f backend/Dockerfile.golang --build-arg BACKEND=local-store . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:local-store -f backend/Dockerfile.golang --build-arg BACKEND=local-store . docker-build-huggingface: - docker build -t local-ai-backend:huggingface -f backend/Dockerfile.golang --build-arg BACKEND=huggingface . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:huggingface -f backend/Dockerfile.golang --build-arg BACKEND=huggingface . docker-save-huggingface: backend-images docker save local-ai-backend:huggingface -o backend-images/huggingface.tar @@ -470,7 +470,7 @@ docker-save-local-store: backend-images docker save local-ai-backend:local-store -o backend-images/local-store.tar docker-build-silero-vad: - docker build -t local-ai-backend:silero-vad -f backend/Dockerfile.golang --build-arg BACKEND=silero-vad . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:silero-vad -f backend/Dockerfile.golang --build-arg BACKEND=silero-vad . docker-save-silero-vad: backend-images docker save local-ai-backend:silero-vad -o backend-images/silero-vad.tar @@ -485,25 +485,25 @@ docker-save-bark-cpp: backend-images docker save local-ai-backend:bark-cpp -o backend-images/bark-cpp.tar docker-build-stablediffusion-ggml: - docker build -t local-ai-backend:stablediffusion-ggml -f backend/Dockerfile.golang --build-arg BACKEND=stablediffusion-ggml . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:stablediffusion-ggml -f backend/Dockerfile.golang --build-arg BACKEND=stablediffusion-ggml . docker-save-stablediffusion-ggml: backend-images docker save local-ai-backend:stablediffusion-ggml -o backend-images/stablediffusion-ggml.tar docker-build-rerankers: - docker build -t local-ai-backend:rerankers -f backend/Dockerfile.python --build-arg BACKEND=rerankers . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:rerankers -f backend/Dockerfile.python --build-arg BACKEND=rerankers . docker-build-vllm: - docker build -t local-ai-backend:vllm -f backend/Dockerfile.python --build-arg BACKEND=vllm . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:vllm -f backend/Dockerfile.python --build-arg BACKEND=vllm . docker-build-transformers: - docker build -t local-ai-backend:transformers -f backend/Dockerfile.python --build-arg BACKEND=transformers . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:transformers -f backend/Dockerfile.python --build-arg BACKEND=transformers . docker-build-diffusers: - docker build -t local-ai-backend:diffusers -f backend/Dockerfile.python --build-arg BACKEND=diffusers . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:diffusers -f backend/Dockerfile.python --build-arg BACKEND=diffusers . docker-build-kokoro: - docker build -t local-ai-backend:kokoro -f backend/Dockerfile.python --build-arg BACKEND=kokoro . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:kokoro -f backend/Dockerfile.python --build-arg BACKEND=kokoro . docker-build-whisper: docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:whisper -f backend/Dockerfile.golang --build-arg BACKEND=whisper . @@ -512,19 +512,19 @@ docker-save-whisper: backend-images docker save local-ai-backend:whisper -o backend-images/whisper.tar docker-build-faster-whisper: - docker build -t local-ai-backend:faster-whisper -f backend/Dockerfile.python --build-arg BACKEND=faster-whisper . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:faster-whisper -f backend/Dockerfile.python --build-arg BACKEND=faster-whisper . docker-build-coqui: - docker build -t local-ai-backend:coqui -f backend/Dockerfile.python --build-arg BACKEND=coqui . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:coqui -f backend/Dockerfile.python --build-arg BACKEND=coqui . docker-build-bark: - docker build -t local-ai-backend:bark -f backend/Dockerfile.python --build-arg BACKEND=bark . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:bark -f backend/Dockerfile.python --build-arg BACKEND=bark . docker-build-chatterbox: - docker build -t local-ai-backend:chatterbox -f backend/Dockerfile.python --build-arg BACKEND=chatterbox . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:chatterbox -f backend/Dockerfile.python --build-arg BACKEND=chatterbox . docker-build-exllama2: - docker build -t local-ai-backend:exllama2 -f backend/Dockerfile.python --build-arg BACKEND=exllama2 . + docker build --build-arg BUILD_TYPE=$(BUILD_TYPE) --build-arg BASE_IMAGE=$(BASE_IMAGE) -t local-ai-backend:exllama2 -f backend/Dockerfile.python --build-arg BACKEND=exllama2 . docker-build-backends: docker-build-llama-cpp docker-build-rerankers docker-build-vllm docker-build-transformers docker-build-diffusers docker-build-kokoro docker-build-faster-whisper docker-build-coqui docker-build-bark docker-build-chatterbox docker-build-exllama2