mirror of
https://github.com/mudler/LocalAI.git
synced 2024-12-19 20:57:54 +00:00
feat(backend): add stablediffusion-ggml (#4289)
* feat(backend): add stablediffusion-ggml Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * chore(ci): track stablediffusion-ggml Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fixups Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * Use default scheduler and sampler if not specified Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fixups Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * Move cfg scale out of diffusers block Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * Make it working Signed-off-by: Ettore Di Giacinto <mudler@localai.io> * fix: set free_params_immediately to false to call the model in sequence https://github.com/leejet/stable-diffusion.cpp/issues/366 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> --------- Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
parent
074b52bbfe
commit
44a5dac312
3
.github/workflows/bump_deps.yaml
vendored
3
.github/workflows/bump_deps.yaml
vendored
@ -18,6 +18,9 @@ jobs:
|
|||||||
- repository: "PABannier/bark.cpp"
|
- repository: "PABannier/bark.cpp"
|
||||||
variable: "BARKCPP_VERSION"
|
variable: "BARKCPP_VERSION"
|
||||||
branch: "main"
|
branch: "main"
|
||||||
|
- repository: "leejet/stable-diffusion.cpp"
|
||||||
|
variable: "STABLEDIFFUSION_GGML_VERSION"
|
||||||
|
branch: "master"
|
||||||
- repository: "mudler/go-stable-diffusion"
|
- repository: "mudler/go-stable-diffusion"
|
||||||
variable: "STABLEDIFFUSION_VERSION"
|
variable: "STABLEDIFFUSION_VERSION"
|
||||||
branch: "master"
|
branch: "master"
|
||||||
|
45
Makefile
45
Makefile
@ -30,6 +30,10 @@ TINYDREAM_VERSION?=c04fa463ace9d9a6464313aa5f9cd0f953b6c057
|
|||||||
BARKCPP_REPO?=https://github.com/PABannier/bark.cpp.git
|
BARKCPP_REPO?=https://github.com/PABannier/bark.cpp.git
|
||||||
BARKCPP_VERSION?=v1.0.0
|
BARKCPP_VERSION?=v1.0.0
|
||||||
|
|
||||||
|
# stablediffusion.cpp (ggml)
|
||||||
|
STABLEDIFFUSION_GGML_REPO?=https://github.com/leejet/stable-diffusion.cpp
|
||||||
|
STABLEDIFFUSION_GGML_VERSION?=4570715727f35e5a07a76796d823824c8f42206c
|
||||||
|
|
||||||
ONNX_VERSION?=1.20.0
|
ONNX_VERSION?=1.20.0
|
||||||
ONNX_ARCH?=x64
|
ONNX_ARCH?=x64
|
||||||
ONNX_OS?=linux
|
ONNX_OS?=linux
|
||||||
@ -209,6 +213,7 @@ ALL_GRPC_BACKENDS+=backend-assets/grpc/whisper
|
|||||||
ifeq ($(ONNX_OS),linux)
|
ifeq ($(ONNX_OS),linux)
|
||||||
ifeq ($(ONNX_ARCH),x64)
|
ifeq ($(ONNX_ARCH),x64)
|
||||||
ALL_GRPC_BACKENDS+=backend-assets/grpc/bark-cpp
|
ALL_GRPC_BACKENDS+=backend-assets/grpc/bark-cpp
|
||||||
|
ALL_GRPC_BACKENDS+=backend-assets/grpc/stablediffusion-ggml
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -244,15 +249,19 @@ sources/go-llama.cpp:
|
|||||||
git checkout $(GOLLAMA_VERSION) && \
|
git checkout $(GOLLAMA_VERSION) && \
|
||||||
git submodule update --init --recursive --depth 1 --single-branch
|
git submodule update --init --recursive --depth 1 --single-branch
|
||||||
|
|
||||||
|
sources/go-llama.cpp/libbinding.a: sources/go-llama.cpp
|
||||||
|
$(MAKE) -C sources/go-llama.cpp BUILD_TYPE=$(STABLE_BUILD_TYPE) libbinding.a
|
||||||
|
|
||||||
|
## bark.cpp
|
||||||
sources/bark.cpp:
|
sources/bark.cpp:
|
||||||
git clone --recursive https://github.com/PABannier/bark.cpp.git sources/bark.cpp && \
|
git clone --recursive $(BARKCPP_REPO) sources/bark.cpp && \
|
||||||
cd sources/bark.cpp && \
|
cd sources/bark.cpp && \
|
||||||
git checkout $(BARKCPP_VERSION) && \
|
git checkout $(BARKCPP_VERSION) && \
|
||||||
git submodule update --init --recursive --depth 1 --single-branch
|
git submodule update --init --recursive --depth 1 --single-branch
|
||||||
|
|
||||||
sources/bark.cpp/build/libbark.a: sources/bark.cpp
|
sources/bark.cpp/build/libbark.a: sources/bark.cpp
|
||||||
cd sources/bark.cpp && \
|
cd sources/bark.cpp && \
|
||||||
mkdir build && \
|
mkdir -p build && \
|
||||||
cd build && \
|
cd build && \
|
||||||
cmake $(CMAKE_ARGS) .. && \
|
cmake $(CMAKE_ARGS) .. && \
|
||||||
cmake --build . --config Release
|
cmake --build . --config Release
|
||||||
@ -260,9 +269,6 @@ sources/bark.cpp/build/libbark.a: sources/bark.cpp
|
|||||||
backend/go/bark/libbark.a: sources/bark.cpp/build/libbark.a
|
backend/go/bark/libbark.a: sources/bark.cpp/build/libbark.a
|
||||||
$(MAKE) -C backend/go/bark libbark.a
|
$(MAKE) -C backend/go/bark libbark.a
|
||||||
|
|
||||||
sources/go-llama.cpp/libbinding.a: sources/go-llama.cpp
|
|
||||||
$(MAKE) -C sources/go-llama.cpp BUILD_TYPE=$(STABLE_BUILD_TYPE) libbinding.a
|
|
||||||
|
|
||||||
## go-piper
|
## go-piper
|
||||||
sources/go-piper:
|
sources/go-piper:
|
||||||
mkdir -p sources/go-piper
|
mkdir -p sources/go-piper
|
||||||
@ -276,7 +282,7 @@ sources/go-piper:
|
|||||||
sources/go-piper/libpiper_binding.a: sources/go-piper
|
sources/go-piper/libpiper_binding.a: sources/go-piper
|
||||||
$(MAKE) -C sources/go-piper libpiper_binding.a example/main piper.o
|
$(MAKE) -C sources/go-piper libpiper_binding.a example/main piper.o
|
||||||
|
|
||||||
## stable diffusion
|
## stable diffusion (onnx)
|
||||||
sources/go-stable-diffusion:
|
sources/go-stable-diffusion:
|
||||||
mkdir -p sources/go-stable-diffusion
|
mkdir -p sources/go-stable-diffusion
|
||||||
cd sources/go-stable-diffusion && \
|
cd sources/go-stable-diffusion && \
|
||||||
@ -289,6 +295,30 @@ sources/go-stable-diffusion:
|
|||||||
sources/go-stable-diffusion/libstablediffusion.a: sources/go-stable-diffusion
|
sources/go-stable-diffusion/libstablediffusion.a: sources/go-stable-diffusion
|
||||||
CPATH="$(CPATH):/usr/include/opencv4" $(MAKE) -C sources/go-stable-diffusion libstablediffusion.a
|
CPATH="$(CPATH):/usr/include/opencv4" $(MAKE) -C sources/go-stable-diffusion libstablediffusion.a
|
||||||
|
|
||||||
|
## stablediffusion (ggml)
|
||||||
|
sources/stablediffusion-ggml.cpp:
|
||||||
|
git clone --recursive $(STABLEDIFFUSION_GGML_REPO) sources/stablediffusion-ggml.cpp && \
|
||||||
|
cd sources/stablediffusion-ggml.cpp && \
|
||||||
|
git checkout $(STABLEDIFFUSION_GGML_VERSION) && \
|
||||||
|
git submodule update --init --recursive --depth 1 --single-branch
|
||||||
|
|
||||||
|
sources/stablediffusion-ggml.cpp/build/libstable-diffusion.a: sources/stablediffusion-ggml.cpp
|
||||||
|
cd sources/stablediffusion-ggml.cpp && \
|
||||||
|
mkdir -p build && \
|
||||||
|
cd build && \
|
||||||
|
cmake $(CMAKE_ARGS) .. && \
|
||||||
|
cmake --build . --config Release
|
||||||
|
|
||||||
|
backend/go/image/stablediffusion-ggml/libsd.a: sources/stablediffusion-ggml.cpp/build/libstable-diffusion.a
|
||||||
|
$(MAKE) -C backend/go/image/stablediffusion-ggml libsd.a
|
||||||
|
|
||||||
|
backend-assets/grpc/stablediffusion-ggml: backend/go/image/stablediffusion-ggml/libsd.a backend-assets/grpc
|
||||||
|
CGO_LDFLAGS="$(CGO_LDFLAGS)" C_INCLUDE_PATH=$(CURDIR)/backend/go/image/stablediffusion-ggml/ LIBRARY_PATH=$(CURDIR)/backend/go/image/stablediffusion-ggml/ \
|
||||||
|
$(GOCMD) build -ldflags "$(LD_FLAGS)" -tags "$(GO_TAGS)" -o backend-assets/grpc/stablediffusion-ggml ./backend/go/image/stablediffusion-ggml/
|
||||||
|
ifneq ($(UPX),)
|
||||||
|
$(UPX) backend-assets/grpc/stablediffusion-ggml
|
||||||
|
endif
|
||||||
|
|
||||||
sources/onnxruntime:
|
sources/onnxruntime:
|
||||||
mkdir -p sources/onnxruntime
|
mkdir -p sources/onnxruntime
|
||||||
curl -L https://github.com/microsoft/onnxruntime/releases/download/v$(ONNX_VERSION)/onnxruntime-$(ONNX_OS)-$(ONNX_ARCH)-$(ONNX_VERSION).tgz -o sources/onnxruntime/onnxruntime-$(ONNX_OS)-$(ONNX_ARCH)-$(ONNX_VERSION).tgz
|
curl -L https://github.com/microsoft/onnxruntime/releases/download/v$(ONNX_VERSION)/onnxruntime-$(ONNX_OS)-$(ONNX_ARCH)-$(ONNX_VERSION).tgz -o sources/onnxruntime/onnxruntime-$(ONNX_OS)-$(ONNX_ARCH)-$(ONNX_VERSION).tgz
|
||||||
@ -329,7 +359,7 @@ sources/whisper.cpp:
|
|||||||
sources/whisper.cpp/libwhisper.a: sources/whisper.cpp
|
sources/whisper.cpp/libwhisper.a: sources/whisper.cpp
|
||||||
cd sources/whisper.cpp && $(MAKE) libwhisper.a libggml.a
|
cd sources/whisper.cpp && $(MAKE) libwhisper.a libggml.a
|
||||||
|
|
||||||
get-sources: sources/go-llama.cpp sources/go-piper sources/bark.cpp sources/whisper.cpp sources/go-stable-diffusion sources/go-tiny-dream backend/cpp/llama/llama.cpp
|
get-sources: sources/go-llama.cpp sources/go-piper sources/stablediffusion-ggml.cpp sources/bark.cpp sources/whisper.cpp sources/go-stable-diffusion sources/go-tiny-dream backend/cpp/llama/llama.cpp
|
||||||
|
|
||||||
replace:
|
replace:
|
||||||
$(GOCMD) mod edit -replace github.com/ggerganov/whisper.cpp=$(CURDIR)/sources/whisper.cpp
|
$(GOCMD) mod edit -replace github.com/ggerganov/whisper.cpp=$(CURDIR)/sources/whisper.cpp
|
||||||
@ -372,6 +402,7 @@ clean: ## Remove build related file
|
|||||||
$(MAKE) -C backend/cpp/grpc clean
|
$(MAKE) -C backend/cpp/grpc clean
|
||||||
$(MAKE) -C backend/go/bark clean
|
$(MAKE) -C backend/go/bark clean
|
||||||
$(MAKE) -C backend/cpp/llama clean
|
$(MAKE) -C backend/cpp/llama clean
|
||||||
|
$(MAKE) -C backend/go/image/stablediffusion-ggml clean
|
||||||
rm -rf backend/cpp/llama-* || true
|
rm -rf backend/cpp/llama-* || true
|
||||||
$(MAKE) dropreplace
|
$(MAKE) dropreplace
|
||||||
$(MAKE) protogen-clean
|
$(MAKE) protogen-clean
|
||||||
|
@ -240,6 +240,8 @@ message ModelOptions {
|
|||||||
|
|
||||||
repeated string LoraAdapters = 60;
|
repeated string LoraAdapters = 60;
|
||||||
repeated float LoraScales = 61;
|
repeated float LoraScales = 61;
|
||||||
|
|
||||||
|
repeated string Options = 62;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Result {
|
message Result {
|
||||||
|
21
backend/go/image/stablediffusion-ggml/Makefile
Normal file
21
backend/go/image/stablediffusion-ggml/Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
INCLUDE_PATH := $(abspath ./)
|
||||||
|
LIBRARY_PATH := $(abspath ./)
|
||||||
|
|
||||||
|
AR?=ar
|
||||||
|
|
||||||
|
BUILD_TYPE?=
|
||||||
|
# keep standard at C11 and C++11
|
||||||
|
CXXFLAGS = -I. -I$(INCLUDE_PATH)/../../../../sources/stablediffusion-ggml.cpp/thirdparty -I$(INCLUDE_PATH)/../../../../sources/stablediffusion-ggml.cpp/ggml/include -I$(INCLUDE_PATH)/../../../../sources/stablediffusion-ggml.cpp -O3 -DNDEBUG -std=c++17 -fPIC
|
||||||
|
|
||||||
|
# warnings
|
||||||
|
CXXFLAGS += -Wall -Wextra -Wpedantic -Wcast-qual -Wno-unused-function
|
||||||
|
|
||||||
|
gosd.o:
|
||||||
|
$(CXX) $(CXXFLAGS) gosd.cpp -o gosd.o -c
|
||||||
|
|
||||||
|
libsd.a: gosd.o
|
||||||
|
cp $(INCLUDE_PATH)/../../../../sources/stablediffusion-ggml.cpp/build/libstable-diffusion.a ./libsd.a
|
||||||
|
$(AR) rcs libsd.a gosd.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f gosd.o libsd.a
|
228
backend/go/image/stablediffusion-ggml/gosd.cpp
Normal file
228
backend/go/image/stablediffusion-ggml/gosd.cpp
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "gosd.h"
|
||||||
|
|
||||||
|
// #include "preprocessing.hpp"
|
||||||
|
#include "flux.hpp"
|
||||||
|
#include "stable-diffusion.h"
|
||||||
|
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_STATIC
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_WRITE_STATIC
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
|
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_RESIZE_STATIC
|
||||||
|
#include "stb_image_resize.h"
|
||||||
|
|
||||||
|
// Names of the sampler method, same order as enum sample_method in stable-diffusion.h
|
||||||
|
const char* sample_method_str[] = {
|
||||||
|
"euler_a",
|
||||||
|
"euler",
|
||||||
|
"heun",
|
||||||
|
"dpm2",
|
||||||
|
"dpm++2s_a",
|
||||||
|
"dpm++2m",
|
||||||
|
"dpm++2mv2",
|
||||||
|
"ipndm",
|
||||||
|
"ipndm_v",
|
||||||
|
"lcm",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Names of the sigma schedule overrides, same order as sample_schedule in stable-diffusion.h
|
||||||
|
const char* schedule_str[] = {
|
||||||
|
"default",
|
||||||
|
"discrete",
|
||||||
|
"karras",
|
||||||
|
"exponential",
|
||||||
|
"ays",
|
||||||
|
"gits",
|
||||||
|
};
|
||||||
|
|
||||||
|
sd_ctx_t* sd_c;
|
||||||
|
|
||||||
|
sample_method_t sample_method;
|
||||||
|
|
||||||
|
int load_model(char *model, char* options[], int threads, int diff) {
|
||||||
|
fprintf (stderr, "Loading model!\n");
|
||||||
|
|
||||||
|
char *stableDiffusionModel = "";
|
||||||
|
if (diff == 1 ) {
|
||||||
|
stableDiffusionModel = model;
|
||||||
|
model = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode options. Options are in form optname:optvale, or if booleans only optname.
|
||||||
|
char *clip_l_path = "";
|
||||||
|
char *clip_g_path = "";
|
||||||
|
char *t5xxl_path = "";
|
||||||
|
char *vae_path = "";
|
||||||
|
char *scheduler = "";
|
||||||
|
char *sampler = "";
|
||||||
|
|
||||||
|
// If options is not NULL, parse options
|
||||||
|
for (int i = 0; options[i] != NULL; i++) {
|
||||||
|
char *optname = strtok(options[i], ":");
|
||||||
|
char *optval = strtok(NULL, ":");
|
||||||
|
if (optval == NULL) {
|
||||||
|
optval = "true";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(optname, "clip_l_path")) {
|
||||||
|
clip_l_path = optval;
|
||||||
|
}
|
||||||
|
if (!strcmp(optname, "clip_g_path")) {
|
||||||
|
clip_g_path = optval;
|
||||||
|
}
|
||||||
|
if (!strcmp(optname, "t5xxl_path")) {
|
||||||
|
t5xxl_path = optval;
|
||||||
|
}
|
||||||
|
if (!strcmp(optname, "vae_path")) {
|
||||||
|
vae_path = optval;
|
||||||
|
}
|
||||||
|
if (!strcmp(optname, "scheduler")) {
|
||||||
|
scheduler = optval;
|
||||||
|
}
|
||||||
|
if (!strcmp(optname, "sampler")) {
|
||||||
|
sampler = optval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sample_method_found = -1;
|
||||||
|
for (int m = 0; m < N_SAMPLE_METHODS; m++) {
|
||||||
|
if (!strcmp(sampler, sample_method_str[m])) {
|
||||||
|
sample_method_found = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sample_method_found == -1) {
|
||||||
|
fprintf(stderr, "Invalid sample method, default to EULER_A!\n");
|
||||||
|
sample_method_found = EULER_A;
|
||||||
|
}
|
||||||
|
sample_method = (sample_method_t)sample_method_found;
|
||||||
|
|
||||||
|
int schedule_found = -1;
|
||||||
|
for (int d = 0; d < N_SCHEDULES; d++) {
|
||||||
|
if (!strcmp(scheduler, schedule_str[d])) {
|
||||||
|
schedule_found = d;
|
||||||
|
fprintf (stderr, "Found scheduler: %s\n", scheduler);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schedule_found == -1) {
|
||||||
|
fprintf (stderr, "Invalid scheduler! using DEFAULT\n");
|
||||||
|
schedule_found = DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (sd_ctx == NULL) {
|
||||||
|
fprintf (stderr, "failed loading model (generic error)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf (stderr, "Created context: OK\n");
|
||||||
|
|
||||||
|
sd_c = sd_ctx;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gen_image(char *text, char *negativeText, int width, int height, int steps, int seed , char *dst, float cfg_scale) {
|
||||||
|
|
||||||
|
sd_image_t* results;
|
||||||
|
|
||||||
|
std::vector<int> skip_layers = {7, 8, 9};
|
||||||
|
|
||||||
|
fprintf (stderr, "Generating image\n");
|
||||||
|
|
||||||
|
results = txt2img(sd_c,
|
||||||
|
text,
|
||||||
|
negativeText,
|
||||||
|
-1, //clip_skip
|
||||||
|
cfg_scale, // sfg_scale
|
||||||
|
3.5f,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
sample_method,
|
||||||
|
steps,
|
||||||
|
seed,
|
||||||
|
1,
|
||||||
|
NULL,
|
||||||
|
0.9f,
|
||||||
|
20.f,
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
skip_layers.data(),
|
||||||
|
skip_layers.size(),
|
||||||
|
0,
|
||||||
|
0.01,
|
||||||
|
0.2);
|
||||||
|
|
||||||
|
if (results == NULL) {
|
||||||
|
fprintf (stderr, "NO results\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results[0].data == NULL) {
|
||||||
|
fprintf (stderr, "Results with no data\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (stderr, "Writing PNG\n");
|
||||||
|
|
||||||
|
fprintf (stderr, "DST: %s\n", dst);
|
||||||
|
fprintf (stderr, "Width: %d\n", results[0].width);
|
||||||
|
fprintf (stderr, "Height: %d\n", results[0].height);
|
||||||
|
fprintf (stderr, "Channel: %d\n", results[0].channel);
|
||||||
|
fprintf (stderr, "Data: %p\n", results[0].data);
|
||||||
|
|
||||||
|
stbi_write_png(dst, results[0].width, results[0].height, results[0].channel,
|
||||||
|
results[0].data, 0, NULL);
|
||||||
|
fprintf (stderr, "Saved resulting image to '%s'\n", dst);
|
||||||
|
|
||||||
|
// TODO: free results. Why does it crash?
|
||||||
|
|
||||||
|
free(results[0].data);
|
||||||
|
results[0].data = NULL;
|
||||||
|
free(results);
|
||||||
|
fprintf (stderr, "gen_image is done", dst);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unload() {
|
||||||
|
free_sd_ctx(sd_c);
|
||||||
|
}
|
||||||
|
|
96
backend/go/image/stablediffusion-ggml/gosd.go
Normal file
96
backend/go/image/stablediffusion-ggml/gosd.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// #cgo CXXFLAGS: -I${SRCDIR}/../../../../sources/stablediffusion-ggml.cpp/thirdparty -I${SRCDIR}/../../../../sources/stablediffusion-ggml.cpp -I${SRCDIR}/../../../../sources/stablediffusion-ggml.cpp/ggml/include
|
||||||
|
// #cgo LDFLAGS: -L${SRCDIR}/ -L${SRCDIR}/../../../../sources/stablediffusion-ggml.cpp/build/ggml/src/ggml-cpu -L${SRCDIR}/../../../../sources/stablediffusion-ggml.cpp/build/ggml/src -lsd -lstdc++ -lm -lggml -lggml-base -lggml-cpu -lgomp
|
||||||
|
// #include <gosd.h>
|
||||||
|
// #include <stdlib.h>
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/mudler/LocalAI/pkg/grpc/base"
|
||||||
|
pb "github.com/mudler/LocalAI/pkg/grpc/proto"
|
||||||
|
"github.com/mudler/LocalAI/pkg/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SDGGML struct {
|
||||||
|
base.SingleThread
|
||||||
|
threads int
|
||||||
|
sampleMethod string
|
||||||
|
cfgScale float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sd *SDGGML) Load(opts *pb.ModelOptions) error {
|
||||||
|
|
||||||
|
sd.threads = int(opts.Threads)
|
||||||
|
|
||||||
|
modelFile := C.CString(opts.ModelFile)
|
||||||
|
defer C.free(unsafe.Pointer(modelFile))
|
||||||
|
|
||||||
|
var options **C.char
|
||||||
|
// prepare the options array to pass to C
|
||||||
|
|
||||||
|
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)]
|
||||||
|
|
||||||
|
var diffusionModel int
|
||||||
|
|
||||||
|
var oo []string
|
||||||
|
for _, op := range opts.Options {
|
||||||
|
if op == "diffusion_model" {
|
||||||
|
diffusionModel = 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's an option path, we resolve absolute path from the model path
|
||||||
|
if strings.Contains(op, ":") && strings.Contains(op, "path") {
|
||||||
|
data := strings.Split(op, ":")
|
||||||
|
data[1] = filepath.Join(opts.ModelPath, data[1])
|
||||||
|
if err := utils.VerifyPath(data[1], opts.ModelPath); err == nil {
|
||||||
|
oo = append(oo, strings.Join(data, ":"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
oo = append(oo, op)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(os.Stderr, "Options: %+v\n", oo)
|
||||||
|
|
||||||
|
for i, x := range oo {
|
||||||
|
view[i] = C.CString(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
sd.cfgScale = opts.CFGScale
|
||||||
|
|
||||||
|
ret := C.load_model(modelFile, options, C.int(opts.Threads), C.int(diffusionModel))
|
||||||
|
if ret != 0 {
|
||||||
|
return fmt.Errorf("could not load model")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sd *SDGGML) GenerateImage(opts *pb.GenerateImageRequest) error {
|
||||||
|
t := C.CString(opts.PositivePrompt)
|
||||||
|
defer C.free(unsafe.Pointer(t))
|
||||||
|
|
||||||
|
dst := C.CString(opts.Dst)
|
||||||
|
defer C.free(unsafe.Pointer(dst))
|
||||||
|
|
||||||
|
negative := C.CString(opts.NegativePrompt)
|
||||||
|
defer C.free(unsafe.Pointer(negative))
|
||||||
|
|
||||||
|
ret := C.gen_image(t, negative, C.int(opts.Width), C.int(opts.Height), C.int(opts.Step), C.int(opts.Seed), dst, C.float(sd.cfgScale))
|
||||||
|
if ret != 0 {
|
||||||
|
return fmt.Errorf("inference failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
8
backend/go/image/stablediffusion-ggml/gosd.h
Normal file
8
backend/go/image/stablediffusion-ggml/gosd.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int load_model(char *model, char* options[], int threads, int diffusionModel);
|
||||||
|
int gen_image(char *text, char *negativeText, int width, int height, int steps, int seed, char *dst, float cfg_scale);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
20
backend/go/image/stablediffusion-ggml/main.go
Normal file
20
backend/go/image/stablediffusion-ggml/main.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// Note: this is started internally by LocalAI and a server is allocated for each model
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
|
||||||
|
grpc "github.com/mudler/LocalAI/pkg/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
addr = flag.String("addr", "localhost:50051", "the address to connect to")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if err := grpc.StartServer(*addr, &SDGGML{}); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
@ -122,7 +122,7 @@ func grpcModelOpts(c config.BackendConfig) *pb.ModelOptions {
|
|||||||
CUDA: c.CUDA || c.Diffusers.CUDA,
|
CUDA: c.CUDA || c.Diffusers.CUDA,
|
||||||
SchedulerType: c.Diffusers.SchedulerType,
|
SchedulerType: c.Diffusers.SchedulerType,
|
||||||
PipelineType: c.Diffusers.PipelineType,
|
PipelineType: c.Diffusers.PipelineType,
|
||||||
CFGScale: c.Diffusers.CFGScale,
|
CFGScale: c.CFGScale,
|
||||||
LoraAdapter: c.LoraAdapter,
|
LoraAdapter: c.LoraAdapter,
|
||||||
LoraScale: c.LoraScale,
|
LoraScale: c.LoraScale,
|
||||||
LoraAdapters: c.LoraAdapters,
|
LoraAdapters: c.LoraAdapters,
|
||||||
@ -132,6 +132,7 @@ func grpcModelOpts(c config.BackendConfig) *pb.ModelOptions {
|
|||||||
IMG2IMG: c.Diffusers.IMG2IMG,
|
IMG2IMG: c.Diffusers.IMG2IMG,
|
||||||
CLIPModel: c.Diffusers.ClipModel,
|
CLIPModel: c.Diffusers.ClipModel,
|
||||||
CLIPSubfolder: c.Diffusers.ClipSubFolder,
|
CLIPSubfolder: c.Diffusers.ClipSubFolder,
|
||||||
|
Options: c.Options,
|
||||||
CLIPSkip: int32(c.Diffusers.ClipSkip),
|
CLIPSkip: int32(c.Diffusers.ClipSkip),
|
||||||
ControlNet: c.Diffusers.ControlNet,
|
ControlNet: c.Diffusers.ControlNet,
|
||||||
ContextSize: int32(ctxSize),
|
ContextSize: int32(ctxSize),
|
||||||
|
@ -72,6 +72,8 @@ type BackendConfig struct {
|
|||||||
|
|
||||||
Description string `yaml:"description"`
|
Description string `yaml:"description"`
|
||||||
Usage string `yaml:"usage"`
|
Usage string `yaml:"usage"`
|
||||||
|
|
||||||
|
Options []string `yaml:"options"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
@ -97,16 +99,15 @@ type GRPC struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Diffusers struct {
|
type Diffusers struct {
|
||||||
CUDA bool `yaml:"cuda"`
|
CUDA bool `yaml:"cuda"`
|
||||||
PipelineType string `yaml:"pipeline_type"`
|
PipelineType string `yaml:"pipeline_type"`
|
||||||
SchedulerType string `yaml:"scheduler_type"`
|
SchedulerType string `yaml:"scheduler_type"`
|
||||||
EnableParameters string `yaml:"enable_parameters"` // A list of comma separated parameters to specify
|
EnableParameters string `yaml:"enable_parameters"` // A list of comma separated parameters to specify
|
||||||
CFGScale float32 `yaml:"cfg_scale"` // Classifier-Free Guidance Scale
|
IMG2IMG bool `yaml:"img2img"` // Image to Image Diffuser
|
||||||
IMG2IMG bool `yaml:"img2img"` // Image to Image Diffuser
|
ClipSkip int `yaml:"clip_skip"` // Skip every N frames
|
||||||
ClipSkip int `yaml:"clip_skip"` // Skip every N frames
|
ClipModel string `yaml:"clip_model"` // Clip model to use
|
||||||
ClipModel string `yaml:"clip_model"` // Clip model to use
|
ClipSubFolder string `yaml:"clip_subfolder"` // Subfolder to use for clip model
|
||||||
ClipSubFolder string `yaml:"clip_subfolder"` // Subfolder to use for clip model
|
ControlNet string `yaml:"control_net"`
|
||||||
ControlNet string `yaml:"control_net"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLMConfig is a struct that holds the configuration that are
|
// LLMConfig is a struct that holds the configuration that are
|
||||||
@ -164,6 +165,8 @@ type LLMConfig struct {
|
|||||||
YarnAttnFactor float32 `yaml:"yarn_attn_factor"`
|
YarnAttnFactor float32 `yaml:"yarn_attn_factor"`
|
||||||
YarnBetaFast float32 `yaml:"yarn_beta_fast"`
|
YarnBetaFast float32 `yaml:"yarn_beta_fast"`
|
||||||
YarnBetaSlow float32 `yaml:"yarn_beta_slow"`
|
YarnBetaSlow float32 `yaml:"yarn_beta_slow"`
|
||||||
|
|
||||||
|
CFGScale float32 `yaml:"cfg_scale"` // Classifier-Free Guidance Scale
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutoGPTQ is a struct that holds the configuration specific to the AutoGPTQ backend
|
// AutoGPTQ is a struct that holds the configuration specific to the AutoGPTQ backend
|
||||||
|
@ -194,8 +194,9 @@ diffusers:
|
|||||||
pipeline_type: StableDiffusionPipeline
|
pipeline_type: StableDiffusionPipeline
|
||||||
enable_parameters: "negative_prompt,num_inference_steps,clip_skip"
|
enable_parameters: "negative_prompt,num_inference_steps,clip_skip"
|
||||||
scheduler_type: "k_dpmpp_sde"
|
scheduler_type: "k_dpmpp_sde"
|
||||||
cfg_scale: 8
|
|
||||||
clip_skip: 11
|
clip_skip: 11
|
||||||
|
|
||||||
|
cfg_scale: 8
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Configuration parameters
|
#### Configuration parameters
|
||||||
@ -302,7 +303,8 @@ cuda: true
|
|||||||
diffusers:
|
diffusers:
|
||||||
pipeline_type: StableDiffusionDepth2ImgPipeline
|
pipeline_type: StableDiffusionDepth2ImgPipeline
|
||||||
enable_parameters: "negative_prompt,num_inference_steps,image"
|
enable_parameters: "negative_prompt,num_inference_steps,image"
|
||||||
cfg_scale: 6
|
|
||||||
|
cfg_scale: 6
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -11,4 +11,5 @@ config_file: |
|
|||||||
cuda: true
|
cuda: true
|
||||||
enable_parameters: num_inference_steps
|
enable_parameters: num_inference_steps
|
||||||
pipeline_type: FluxPipeline
|
pipeline_type: FluxPipeline
|
||||||
cfg_scale: 0
|
|
||||||
|
cfg_scale: 0
|
||||||
|
Loading…
Reference in New Issue
Block a user