Skip to content

Commit a6cd69e

Browse files
committed
fixups
1 parent c30e276 commit a6cd69e

File tree

6 files changed

+124
-36
lines changed

6 files changed

+124
-36
lines changed

backend/backend.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ message ModelOptions {
240240

241241
repeated string LoraAdapters = 60;
242242
repeated float LoraScales = 61;
243+
244+
repeated string Options = 62;
243245
}
244246

245247
message Result {

backend/go/image/stablediffusion-ggml/gosd.cpp

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -180,29 +180,88 @@ void print_params(SDParams params) {
180180

181181
sd_ctx_t* sd_c;
182182

183-
int load_model(char *model, char *schedule_selected, int threads) {
183+
sample_method_t sample_method;
184+
185+
int load_model(char *model, char* options[], int threads, int diff) {
184186
fprintf (stderr, "Loading model!\n");
185187

188+
char *stableDiffusionModel = "";
189+
if (diff == 1 ) {
190+
stableDiffusionModel = model;
191+
model = "";
192+
}
193+
194+
// decode options. Options are in form optname:optvale, or if booleans only optname.
195+
char *clip_l_path = "";
196+
char *clip_g_path = "";
197+
char *t5xxl_path = "";
198+
char *vae_path = "";
199+
char *scheduler = "";
200+
char *sampler = "";
201+
202+
// If options is not NULL, parse options
203+
for (int i = 0; options[i] != NULL; i++) {
204+
char *optname = strtok(options[i], ":");
205+
char *optval = strtok(NULL, ":");
206+
if (optval == NULL) {
207+
optval = "true";
208+
}
209+
210+
if (!strcmp(optname, "clip_l_path")) {
211+
clip_l_path = optval;
212+
}
213+
if (!strcmp(optname, "clip_g_path")) {
214+
clip_g_path = optval;
215+
}
216+
if (!strcmp(optname, "t5xxl_path")) {
217+
t5xxl_path = optval;
218+
}
219+
if (!strcmp(optname, "vae_path")) {
220+
vae_path = optval;
221+
}
222+
if (!strcmp(optname, "scheduler")) {
223+
scheduler = optval;
224+
}
225+
if (!strcmp(optname, "sampler")) {
226+
sampler = optval;
227+
}
228+
}
229+
230+
int sample_method_found = -1;
231+
for (int m = 0; m < N_SAMPLE_METHODS; m++) {
232+
if (!strcmp(sampler, sample_method_str[m])) {
233+
sample_method_found = m;
234+
}
235+
}
236+
if (sample_method_found == -1) {
237+
fprintf(stderr, "Invalid sample method, default to EULER_A!\n");
238+
sample_method_found = EULER_A;
239+
}
240+
sample_method = (sample_method_t)sample_method_found;
241+
186242
int schedule_found = -1;
187243
for (int d = 0; d < N_SCHEDULES; d++) {
188-
if (!strcmp(schedule_selected, schedule_str[d])) {
244+
if (!strcmp(scheduler, schedule_str[d])) {
189245
schedule_found = d;
246+
fprintf (stderr, "Found scheduler: %s\n", scheduler);
247+
190248
}
191249
}
250+
192251
if (schedule_found == -1) {
193252
fprintf (stderr, "Invalid scheduler! using DEFAULT\n");
194253
schedule_found = DEFAULT;
195254
}
196255

197-
198256
schedule_t schedule = (schedule_t)schedule_found;
199-
257+
258+
fprintf (stderr, "Creating context\n");
200259
sd_ctx_t* sd_ctx = new_sd_ctx(model,
201-
"",
202-
"",
203-
"",
204-
"",
205-
"",
260+
clip_l_path,
261+
clip_g_path,
262+
t5xxl_path,
263+
stableDiffusionModel,
264+
vae_path,
206265
"",
207266
"",
208267
"",
@@ -221,38 +280,26 @@ int load_model(char *model, char *schedule_selected, int threads) {
221280
false);
222281

223282
if (sd_ctx == NULL) {
224-
fprintf (stderr, "Null context!\n");
283+
fprintf (stderr, "failed loading model (generic error)\n");
225284
return 1;
226285
}
286+
fprintf (stderr, "Created context: OK\n");
227287

228288
sd_c = sd_ctx;
229289

230290
return 0;
231291
}
232292

233-
int gen_image(char *text, char *negativeText, int width, int height, int steps, int seed , char* sample_method_selected, char *dst ) {
293+
int gen_image(char *text, char *negativeText, int width, int height, int steps, int seed , char *dst, float cfg_scale) {
234294

235295
sd_image_t* results;
236296

237-
238-
int sample_method_found = -1;
239-
for (int m = 0; m < N_SAMPLE_METHODS; m++) {
240-
if (!strcmp(sample_method_selected, sample_method_str[m])) {
241-
sample_method_found = m;
242-
}
243-
}
244-
if (sample_method_found == -1) {
245-
fprintf(stderr, "Invalid sample method, default to EULER_A!\n");
246-
sample_method_found = EULER_A;
247-
return 1;
248-
}
249-
sample_method_t sample_method = (sample_method_t)sample_method_found;
250297
std::vector<int> skip_layers = {7, 8, 9};
251298
results = txt2img(sd_c,
252299
text,
253300
negativeText,
254301
-1, //clip_skip
255-
7.0f, // sfg_scale
302+
cfg_scale, // sfg_scale
256303
3.5f,
257304
width,
258305
height,

backend/go/image/stablediffusion-ggml/gosd.go

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,67 @@ import "C"
88

99
import (
1010
"fmt"
11+
"os"
12+
"path/filepath"
13+
"strings"
1114
"unsafe"
1215

1316
"github.com/mudler/LocalAI/pkg/grpc/base"
1417
pb "github.com/mudler/LocalAI/pkg/grpc/proto"
18+
"github.com/mudler/LocalAI/pkg/utils"
1519
)
1620

1721
type SDGGML struct {
1822
base.SingleThread
19-
threads int
23+
threads int
24+
sampleMethod string
25+
cfgScale float32
2026
}
2127

2228
func (sd *SDGGML) Load(opts *pb.ModelOptions) error {
2329

2430
sd.threads = int(opts.Threads)
2531

26-
schedulerType := C.CString(opts.SchedulerType)
27-
defer C.free(unsafe.Pointer(schedulerType))
28-
2932
modelFile := C.CString(opts.ModelFile)
3033
defer C.free(unsafe.Pointer(modelFile))
3134

32-
ret := C.load_model(modelFile, schedulerType, C.int(opts.Threads))
35+
var options **C.char
36+
37+
size := C.size_t(unsafe.Sizeof((*C.char)(nil)))
38+
length := C.size_t(len(opts.Options))
39+
options = (**C.char)(C.malloc(length * size))
40+
view := (*[1 << 30]*C.char)(unsafe.Pointer(options))[0:len(opts.Options):len(opts.Options)]
41+
42+
var diffusionModel int
43+
44+
var oo []string
45+
for _, op := range opts.Options {
46+
if op == "diffusion_model" {
47+
diffusionModel = 1
48+
continue
49+
}
50+
51+
// If it's an option path, we resolve absolute path from the model path
52+
if strings.Contains(op, ":") && strings.Contains(op, "path") {
53+
data := strings.Split(op, ":")
54+
data[1] = filepath.Join(opts.ModelPath, data[1])
55+
if err := utils.VerifyPath(data[1], opts.ModelPath); err == nil {
56+
oo = append(oo, strings.Join(data, ":"))
57+
}
58+
} else {
59+
oo = append(oo, op)
60+
}
61+
}
62+
63+
fmt.Fprintf(os.Stderr, "Options: %+v\n", oo)
64+
65+
for i, x := range oo {
66+
view[i] = C.CString(x)
67+
}
68+
69+
sd.cfgScale = opts.CFGScale
70+
71+
ret := C.load_model(modelFile, options, C.int(opts.Threads), C.int(diffusionModel))
3372
if ret != 0 {
3473
return fmt.Errorf("could not load model")
3574
}
@@ -47,10 +86,7 @@ func (sd *SDGGML) GenerateImage(opts *pb.GenerateImageRequest) error {
4786
negative := C.CString(opts.NegativePrompt)
4887
defer C.free(unsafe.Pointer(negative))
4988

50-
sampleMethod := C.CString(opts.EnableParameters)
51-
defer C.free(unsafe.Pointer(sampleMethod))
52-
53-
ret := C.gen_image(t, negative, C.int(opts.Width), C.int(opts.Height), C.int(opts.Step), C.int(opts.Seed), sampleMethod, dst)
89+
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))
5490
if ret != 0 {
5591
return fmt.Errorf("inference failed")
5692
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#ifdef __cplusplus
22
extern "C" {
33
#endif
4-
int load_model(char *model, char *schedule_selected, int threads);
5-
int gen_image(char *text, char *negativeText, int width, int height, int steps, int seed , char* sample_method_selected, char *dst );
4+
int load_model(char *model, char* options[], int threads, int diffusionModel);
5+
int gen_image(char *text, char *negativeText, int width, int height, int steps, int seed, char *dst, float cfg_scale);
66
#ifdef __cplusplus
77
}
88
#endif

core/backend/options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ func grpcModelOpts(c config.BackendConfig) *pb.ModelOptions {
132132
IMG2IMG: c.Diffusers.IMG2IMG,
133133
CLIPModel: c.Diffusers.ClipModel,
134134
CLIPSubfolder: c.Diffusers.ClipSubFolder,
135+
Options: c.Options,
135136
CLIPSkip: int32(c.Diffusers.ClipSkip),
136137
ControlNet: c.Diffusers.ControlNet,
137138
ContextSize: int32(ctxSize),

core/config/backend_config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ type BackendConfig struct {
7272

7373
Description string `yaml:"description"`
7474
Usage string `yaml:"usage"`
75+
76+
Options []string `yaml:"options"`
7577
}
7678

7779
type File struct {

0 commit comments

Comments
 (0)