From acd03d15f211c517f176f893c10de74f2b61eda5 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Tue, 16 May 2023 16:26:25 +0200 Subject: [PATCH 01/18] feat: add support for cublas/openblas in the llama.cpp backend (#258) --- Makefile | 27 +++++++++++++-------------- api/config.go | 34 +++++++++++++++++----------------- api/prediction.go | 4 ++++ 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index 683b5d32..f296a836 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GOTEST=$(GOCMD) test GOVET=$(GOCMD) vet BINARY_NAME=local-ai -GOLLAMA_VERSION?=eb99b5438787cbd687682da445e879e02bfeaa07 +GOLLAMA_VERSION?=7f9ae4246088f0c08ed322acbae21d69cd2eb547 GPT4ALL_REPO?=https://github.com/go-skynet/gpt4all GPT4ALL_VERSION?=a330bfe26e9e35ca402e16df18973a3b162fb4db GOGPT2_VERSION?=92421a8cf61ed6e03babd9067af292b094cb1307 @@ -12,7 +12,9 @@ RWKV_VERSION?=07166da10cb2a9e8854395a4f210464dcea76e47 WHISPER_CPP_VERSION?=a5defbc1b98bea0f070331ce1e8b62d947b0443d BERT_VERSION?=33118e0da50318101408986b86a331daeb4a6658 BLOOMZ_VERSION?=e9366e82abdfe70565644fbfae9651976714efd1 - +BUILD_TYPE?= +CGO_LDFLAGS?= +CUDA_LIBPATH?=/usr/local/cuda/lib64/ GREEN := $(shell tput -Txterm setaf 2) YELLOW := $(shell tput -Txterm setaf 3) @@ -23,15 +25,12 @@ RESET := $(shell tput -Txterm sgr0) C_INCLUDE_PATH=$(shell pwd)/go-llama:$(shell pwd)/gpt4all/gpt4all-bindings/golang/:$(shell pwd)/go-gpt2:$(shell pwd)/go-rwkv:$(shell pwd)/whisper.cpp:$(shell pwd)/go-bert:$(shell pwd)/bloomz LIBRARY_PATH=$(shell pwd)/go-llama:$(shell pwd)/gpt4all/gpt4all-bindings/golang/:$(shell pwd)/go-gpt2:$(shell pwd)/go-rwkv:$(shell pwd)/whisper.cpp:$(shell pwd)/go-bert:$(shell pwd)/bloomz -# Use this if you want to set the default behavior -ifndef BUILD_TYPE - BUILD_TYPE:=default +ifeq ($(BUILD_TYPE),openblas) + CGO_LDFLAGS+=-lopenblas endif -ifeq ($(BUILD_TYPE), "generic") - GENERIC_PREFIX:=generic- -else - GENERIC_PREFIX:= +ifeq ($(BUILD_TYPE),cublas) + CGO_LDFLAGS+=-lcublas -lcudart -L$(CUDA_LIBPATH) endif .PHONY: all test build vendor @@ -94,7 +93,7 @@ go-bert/libgobert.a: go-bert $(MAKE) -C go-bert libgobert.a gpt4all/gpt4all-bindings/golang/libgpt4all.a: gpt4all - $(MAKE) -C gpt4all/gpt4all-bindings/golang/ $(GENERIC_PREFIX)libgpt4all.a + $(MAKE) -C gpt4all/gpt4all-bindings/golang/ libgpt4all.a ## CEREBRAS GPT go-gpt2: @@ -113,7 +112,7 @@ go-gpt2: @find ./go-gpt2 -type f -name "*.cpp" -exec sed -i'' -e 's/json_/json_gpt2_/g' {} + go-gpt2/libgpt2.a: go-gpt2 - $(MAKE) -C go-gpt2 $(GENERIC_PREFIX)libgpt2.a + $(MAKE) -C go-gpt2 libgpt2.a whisper.cpp: git clone https://github.com/ggerganov/whisper.cpp.git @@ -130,7 +129,7 @@ go-llama: cd go-llama && git checkout -b build $(GOLLAMA_VERSION) && git submodule update --init --recursive --depth 1 go-llama/libbinding.a: go-llama - $(MAKE) -C go-llama $(GENERIC_PREFIX)libbinding.a + $(MAKE) -C go-llama BUILD_TYPE=$(BUILD_TYPE) libbinding.a replace: $(GOCMD) mod edit -replace github.com/go-skynet/go-llama.cpp=$(shell pwd)/go-llama @@ -171,14 +170,14 @@ clean: ## Remove build related file build: prepare ## Build the project $(info ${GREEN}I local-ai build info:${RESET}) $(info ${GREEN}I BUILD_TYPE: ${YELLOW}$(BUILD_TYPE)${RESET}) - C_INCLUDE_PATH=${C_INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} $(GOCMD) build -x -o $(BINARY_NAME) ./ + CGO_LDFLAGS="$(CGO_LDFLAGS)" C_INCLUDE_PATH=${C_INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} $(GOCMD) build -x -o $(BINARY_NAME) ./ generic-build: ## Build the project using generic BUILD_TYPE="generic" $(MAKE) build ## Run run: prepare ## run local-ai - C_INCLUDE_PATH=${C_INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} $(GOCMD) run ./main.go + CGO_LDFLAGS="$(CGO_LDFLAGS)" C_INCLUDE_PATH=${C_INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} $(GOCMD) run ./main.go test-models/testmodel: mkdir test-models diff --git a/api/config.go b/api/config.go index 43051286..3791d490 100644 --- a/api/config.go +++ b/api/config.go @@ -15,23 +15,23 @@ import ( ) type Config struct { - OpenAIRequest `yaml:"parameters"` - Name string `yaml:"name"` - StopWords []string `yaml:"stopwords"` - Cutstrings []string `yaml:"cutstrings"` - TrimSpace []string `yaml:"trimspace"` - ContextSize int `yaml:"context_size"` - F16 bool `yaml:"f16"` - Threads int `yaml:"threads"` - Debug bool `yaml:"debug"` - Roles map[string]string `yaml:"roles"` - Embeddings bool `yaml:"embeddings"` - Backend string `yaml:"backend"` - TemplateConfig TemplateConfig `yaml:"template"` - MirostatETA float64 `yaml:"mirostat_eta"` - MirostatTAU float64 `yaml:"mirostat_tau"` - Mirostat int `yaml:"mirostat"` - + OpenAIRequest `yaml:"parameters"` + Name string `yaml:"name"` + StopWords []string `yaml:"stopwords"` + Cutstrings []string `yaml:"cutstrings"` + TrimSpace []string `yaml:"trimspace"` + ContextSize int `yaml:"context_size"` + F16 bool `yaml:"f16"` + Threads int `yaml:"threads"` + Debug bool `yaml:"debug"` + Roles map[string]string `yaml:"roles"` + Embeddings bool `yaml:"embeddings"` + Backend string `yaml:"backend"` + TemplateConfig TemplateConfig `yaml:"template"` + MirostatETA float64 `yaml:"mirostat_eta"` + MirostatTAU float64 `yaml:"mirostat_tau"` + Mirostat int `yaml:"mirostat"` + NGPULayers int `yaml:"gpu_layers"` PromptStrings, InputStrings []string InputToken [][]int } diff --git a/api/prediction.go b/api/prediction.go index 3dfb45fd..7aa839bb 100644 --- a/api/prediction.go +++ b/api/prediction.go @@ -31,6 +31,10 @@ func defaultLLamaOpts(c Config) []llama.ModelOption { llamaOpts = append(llamaOpts, llama.EnableEmbeddings) } + if c.NGPULayers != 0 { + llamaOpts = append(llamaOpts, llama.SetGPULayers(c.NGPULayers)) + } + return llamaOpts } From 9d051c5d4fabdf0a8df464df0a385d2393355377 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Tue, 16 May 2023 19:32:53 +0200 Subject: [PATCH 02/18] feat: add image generation with ncnn-stablediffusion (#272) --- .dockerignore | 4 +- .gitignore | 3 +- Makefile | 39 +++- README.md | 217 +++++++++++++++++++- api/api.go | 8 +- api/api_test.go | 4 +- api/config.go | 13 +- api/openai.go | 193 ++++++++++++++++- api/prediction.go | 42 +++- examples/chatbot-ui/README.md | 4 +- go.mod | 3 +- go.sum | 4 + main.go | 8 +- pkg/model/initializers.go | 45 ++-- pkg/stablediffusion/generate.go | 23 +++ pkg/stablediffusion/generate_unsupported.go | 10 + pkg/stablediffusion/stablediffusion.go | 20 ++ 17 files changed, 582 insertions(+), 58 deletions(-) create mode 100644 pkg/stablediffusion/generate.go create mode 100644 pkg/stablediffusion/generate_unsupported.go create mode 100644 pkg/stablediffusion/stablediffusion.go diff --git a/.dockerignore b/.dockerignore index dff08bde..41478502 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,4 @@ models -examples/chatbot-ui/models \ No newline at end of file +examples/chatbot-ui/models +examples/rwkv/models +examples/**/models diff --git a/.gitignore b/.gitignore index 98cdf701..12c461c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # go-llama build artifacts go-llama -go-gpt4all-j +gpt4all +go-stable-diffusion go-gpt2 go-rwkv whisper.cpp diff --git a/Makefile b/Makefile index f296a836..dec3569a 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,8 @@ GOVET=$(GOCMD) vet BINARY_NAME=local-ai GOLLAMA_VERSION?=7f9ae4246088f0c08ed322acbae21d69cd2eb547 -GPT4ALL_REPO?=https://github.com/go-skynet/gpt4all -GPT4ALL_VERSION?=a330bfe26e9e35ca402e16df18973a3b162fb4db +GPT4ALL_REPO?=https://github.com/nomic-ai/gpt4all +GPT4ALL_VERSION?=a07237e54fcdfdb351913587052ac061a2a7bdff GOGPT2_VERSION?=92421a8cf61ed6e03babd9067af292b094cb1307 RWKV_REPO?=https://github.com/donomii/go-rwkv.cpp RWKV_VERSION?=07166da10cb2a9e8854395a4f210464dcea76e47 @@ -15,6 +15,11 @@ BLOOMZ_VERSION?=e9366e82abdfe70565644fbfae9651976714efd1 BUILD_TYPE?= CGO_LDFLAGS?= CUDA_LIBPATH?=/usr/local/cuda/lib64/ +STABLEDIFFUSION_VERSION?=c0748eca3642d58bcf9521108bcee46959c647dc + +GO_TAGS?= + +OPTIONAL_TARGETS?= GREEN := $(shell tput -Txterm setaf 2) YELLOW := $(shell tput -Txterm setaf 3) @@ -22,8 +27,8 @@ WHITE := $(shell tput -Txterm setaf 7) CYAN := $(shell tput -Txterm setaf 6) RESET := $(shell tput -Txterm sgr0) -C_INCLUDE_PATH=$(shell pwd)/go-llama:$(shell pwd)/gpt4all/gpt4all-bindings/golang/:$(shell pwd)/go-gpt2:$(shell pwd)/go-rwkv:$(shell pwd)/whisper.cpp:$(shell pwd)/go-bert:$(shell pwd)/bloomz -LIBRARY_PATH=$(shell pwd)/go-llama:$(shell pwd)/gpt4all/gpt4all-bindings/golang/:$(shell pwd)/go-gpt2:$(shell pwd)/go-rwkv:$(shell pwd)/whisper.cpp:$(shell pwd)/go-bert:$(shell pwd)/bloomz +C_INCLUDE_PATH=$(shell pwd)/go-llama:$(shell pwd)/go-stable-diffusion/:$(shell pwd)/gpt4all/gpt4all-bindings/golang/:$(shell pwd)/go-gpt2:$(shell pwd)/go-rwkv:$(shell pwd)/whisper.cpp:$(shell pwd)/go-bert:$(shell pwd)/bloomz +LIBRARY_PATH=$(shell pwd)/go-llama:$(shell pwd)/go-stable-diffusion/:$(shell pwd)/gpt4all/gpt4all-bindings/golang/:$(shell pwd)/go-gpt2:$(shell pwd)/go-rwkv:$(shell pwd)/whisper.cpp:$(shell pwd)/go-bert:$(shell pwd)/bloomz ifeq ($(BUILD_TYPE),openblas) CGO_LDFLAGS+=-lopenblas @@ -33,6 +38,11 @@ ifeq ($(BUILD_TYPE),cublas) CGO_LDFLAGS+=-lcublas -lcudart -L$(CUDA_LIBPATH) endif + +ifeq ($(GO_TAGS),stablediffusion) + OPTIONAL_TARGETS+=go-stable-diffusion/libstablediffusion.a +endif + .PHONY: all test build vendor all: help @@ -66,6 +76,14 @@ go-bert: @find ./go-bert -type f -name "*.cpp" -exec sed -i'' -e 's/ggml_/ggml_bert_/g' {} + @find ./go-bert -type f -name "*.h" -exec sed -i'' -e 's/ggml_/ggml_bert_/g' {} + +## stable diffusion +go-stable-diffusion: + git clone --recurse-submodules https://github.com/mudler/go-stable-diffusion go-stable-diffusion + cd go-stable-diffusion && git checkout -b build $(STABLEDIFFUSION_VERSION) && git submodule update --init --recursive --depth 1 + +go-stable-diffusion/libstablediffusion.a: + $(MAKE) -C go-stable-diffusion libstablediffusion.a + ## RWKV go-rwkv: git clone --recurse-submodules $(RWKV_REPO) go-rwkv @@ -133,14 +151,15 @@ go-llama/libbinding.a: go-llama replace: $(GOCMD) mod edit -replace github.com/go-skynet/go-llama.cpp=$(shell pwd)/go-llama - $(GOCMD) mod edit -replace github.com/nomic/gpt4all/gpt4all-bindings/golang=$(shell pwd)/gpt4all/gpt4all-bindings/golang + $(GOCMD) mod edit -replace github.com/nomic-ai/gpt4all/gpt4all-bindings/golang=$(shell pwd)/gpt4all/gpt4all-bindings/golang $(GOCMD) mod edit -replace github.com/go-skynet/go-gpt2.cpp=$(shell pwd)/go-gpt2 $(GOCMD) mod edit -replace github.com/donomii/go-rwkv.cpp=$(shell pwd)/go-rwkv $(GOCMD) mod edit -replace github.com/ggerganov/whisper.cpp=$(shell pwd)/whisper.cpp $(GOCMD) mod edit -replace github.com/go-skynet/go-bert.cpp=$(shell pwd)/go-bert $(GOCMD) mod edit -replace github.com/go-skynet/bloomz.cpp=$(shell pwd)/bloomz + $(GOCMD) mod edit -replace github.com/mudler/go-stable-diffusion=$(shell pwd)/go-stable-diffusion -prepare-sources: go-llama go-gpt2 gpt4all go-rwkv whisper.cpp go-bert bloomz replace +prepare-sources: go-llama go-gpt2 gpt4all go-rwkv whisper.cpp go-bert bloomz go-stable-diffusion replace $(GOCMD) mod download ## GENERIC @@ -150,19 +169,22 @@ rebuild: ## Rebuilds the project $(MAKE) -C go-gpt2 clean $(MAKE) -C go-rwkv clean $(MAKE) -C whisper.cpp clean + $(MAKE) -C go-stable-diffusion clean $(MAKE) -C go-bert clean $(MAKE) -C bloomz clean $(MAKE) build -prepare: prepare-sources gpt4all/gpt4all-bindings/golang/libgpt4all.a go-llama/libbinding.a go-bert/libgobert.a go-gpt2/libgpt2.a go-rwkv/librwkv.a whisper.cpp/libwhisper.a bloomz/libbloomz.a ## Prepares for building +prepare: prepare-sources gpt4all/gpt4all-bindings/golang/libgpt4all.a $(OPTIONAL_TARGETS) go-llama/libbinding.a go-bert/libgobert.a go-gpt2/libgpt2.a go-rwkv/librwkv.a whisper.cpp/libwhisper.a bloomz/libbloomz.a ## Prepares for building clean: ## Remove build related file rm -fr ./go-llama rm -rf ./gpt4all + rm -rf ./go-stable-diffusion rm -rf ./go-gpt2 rm -rf ./go-rwkv rm -rf ./go-bert rm -rf ./bloomz + rm -rf ./whisper.cpp rm -rf $(BINARY_NAME) ## Build: @@ -170,7 +192,8 @@ clean: ## Remove build related file build: prepare ## Build the project $(info ${GREEN}I local-ai build info:${RESET}) $(info ${GREEN}I BUILD_TYPE: ${YELLOW}$(BUILD_TYPE)${RESET}) - CGO_LDFLAGS="$(CGO_LDFLAGS)" C_INCLUDE_PATH=${C_INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} $(GOCMD) build -x -o $(BINARY_NAME) ./ + $(info ${GREEN}I GO_TAGS: ${YELLOW}$(GO_TAGS)${RESET}) + CGO_LDFLAGS="$(CGO_LDFLAGS)" C_INCLUDE_PATH=${C_INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} $(GOCMD) build -tags "$(GO_TAGS)" -x -o $(BINARY_NAME) ./ generic-build: ## Build the project using generic BUILD_TYPE="generic" $(MAKE) build diff --git a/README.md b/README.md index fc64e20d..d9986e6d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ **LocalAI** is a drop-in replacement REST API compatible with OpenAI API specifications for local inferencing. It allows to run models locally or on-prem with consumer grade hardware, supporting multiple models families compatible with the `ggml` format. For a list of the supported model families, see [the model compatibility table below](https://github.com/go-skynet/LocalAI#model-compatibility-table). - OpenAI drop-in alternative REST API -- Supports multiple models +- Supports multiple models, Audio transcription, Text generation with GPTs, Image generation with stable diffusion (experimental) - Once loaded the first time, it keep models loaded in memory for faster inference - Support for prompt templates - Doesn't shell-out, but uses C++ bindings for a faster inference and better performance. @@ -23,6 +23,7 @@ LocalAI uses C++ bindings for optimizing speed. It is based on [llama.cpp](https See [examples on how to integrate LocalAI](https://github.com/go-skynet/LocalAI/tree/master/examples/). + ### How does it work?
@@ -33,6 +34,14 @@ See [examples on how to integrate LocalAI](https://github.com/go-skynet/LocalAI/ ## News +- 16-05-2023: 🔥🔥🔥 Experimental support for CUDA (https://github.com/go-skynet/LocalAI/pull/258) in the `llama.cpp` backend and Stable diffusion CPU image generation (https://github.com/go-skynet/LocalAI/pull/272) in `master`. + +Now LocalAI can generate images too: + +| mode=0 | mode=1 (winograd/sgemm) | +|------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------| +| ![b6441997879](https://github.com/go-skynet/LocalAI/assets/2420543/d50af51c-51b7-4f39-b6c2-bf04c403894c) | ![winograd2](https://github.com/go-skynet/LocalAI/assets/2420543/1935a69a-ecce-4afc-a099-1ac28cb649b3) | + - 14-05-2023: __v1.11.1__ released! `rwkv` backend patch release - 13-05-2023: __v1.11.0__ released! 🔥 Updated `llama.cpp` bindings: This update includes a breaking change in the model files ( https://github.com/ggerganov/llama.cpp/pull/1405 ) - old models should still work with the `gpt4all-llama` backend. - 12-05-2023: __v1.10.0__ released! 🔥🔥 Updated `gpt4all` bindings. Added support for GPTNeox (experimental), RedPajama (experimental), Starcoder (experimental), Replit (experimental), MosaicML MPT. Also now `embeddings` endpoint supports tokens arrays. See the [langchain-chroma](https://github.com/go-skynet/LocalAI/tree/master/examples/langchain-chroma) example! Note - this update does NOT include https://github.com/ggerganov/llama.cpp/pull/1405 which makes models incompatible. @@ -106,7 +115,7 @@ Depending on the model you are attempting to run might need more RAM or CPU reso
-| Backend | Compatible models | Completion/Chat endpoint | Audio transcription | Embeddings support | Token stream support | Github | Bindings | +| Backend | Compatible models | Completion/Chat endpoint | Audio transcription/Image | Embeddings support | Token stream support | Github | Bindings | |-----------------|-----------------------|--------------------------|---------------------|-----------------------------------|----------------------|--------------------------------------------|-------------------------------------------| | llama | Vicuna, Alpaca, LLaMa | yes | no | yes (doesn't seem to be accurate) | yes | https://github.com/ggerganov/llama.cpp | https://github.com/go-skynet/go-llama.cpp | | gpt4all-llama | Vicuna, Alpaca, LLaMa | yes | no | no | yes | https://github.com/nomic-ai/gpt4all | https://github.com/go-skynet/gpt4all | @@ -122,8 +131,8 @@ Depending on the model you are attempting to run might need more RAM or CPU reso | bloomz | Bloom | yes | no | no | no | https://github.com/NouamaneTazi/bloomz.cpp | https://github.com/go-skynet/bloomz.cpp | | rwkv | RWKV | yes | no | no | yes | https://github.com/saharNooby/rwkv.cpp | https://github.com/donomii/go-rwkv.cpp | | bert-embeddings | bert | no | no | yes | no | https://github.com/skeskinen/bert.cpp | https://github.com/go-skynet/go-bert.cpp | -| whisper | whisper | no | yes | no | no | https://github.com/ggerganov/whisper.cpp | https://github.com/ggerganov/whisper.cpp | - +| whisper | whisper | no | Audio | no | no | https://github.com/ggerganov/whisper.cpp | https://github.com/ggerganov/whisper.cpp | +| stablediffusion | stablediffusion | no | Image | no | no | https://github.com/EdVince/Stable-Diffusion-NCNN | https://github.com/mudler/go-stable-diffusion |
## Usage @@ -148,7 +157,9 @@ cp your-model.bin models/ # vim .env # start with docker-compose -docker-compose up -d --build +docker-compose up -d --pull always +# or you can build the images with: +# docker-compose up -d --build # Now API is accessible at localhost:8080 curl http://localhost:8080/v1/models @@ -184,8 +195,9 @@ cp -rf prompt-templates/ggml-gpt4all-j.tmpl models/ # vim .env # start with docker-compose -docker-compose up -d --build - +docker-compose up -d --pull always +# or you can build the images with: +# docker-compose up -d --build # Now API is accessible at localhost:8080 curl http://localhost:8080/v1/models # {"object":"list","data":[{"id":"ggml-gpt4all-j","object":"model"}]} @@ -204,6 +216,8 @@ To build locally, run `make build` (see below). ### Other examples +![Screenshot from 2023-04-26 23-59-55](https://user-images.githubusercontent.com/2420543/234715439-98d12e03-d3ce-4f94-ab54-2b256808e05e.png) + To see other examples on how to integrate with other projects for instance for question answering or for using it with chatbot-ui, see: [examples](https://github.com/go-skynet/LocalAI/tree/master/examples/). @@ -294,6 +308,73 @@ Specifying a `config-file` via CLI allows to declare models in a single file as See also [chatbot-ui](https://github.com/go-skynet/LocalAI/tree/master/examples/chatbot-ui) as an example on how to use config files. +### Full config model file reference + +```yaml +name: gpt-3.5-turbo + +# Default model parameters +parameters: + # Relative to the models path + model: ggml-gpt4all-j + # temperature + temperature: 0.3 + # all the OpenAI request options here.. + top_k: + top_p: + max_tokens: + batch: + f16: true + ignore_eos: true + n_keep: 10 + seed: + mode: + step: + +# Default context size +context_size: 512 +# Default number of threads +threads: 10 +# Define a backend (optional). By default it will try to guess the backend the first time the model is interacted with. +backend: gptj # available: llama, stablelm, gpt2, gptj rwkv +# stopwords (if supported by the backend) +stopwords: +- "HUMAN:" +- "### Response:" +# string to trim space to +trimspace: +- string +# Strings to cut from the response +cutstrings: +- "string" +# define chat roles +roles: + user: "HUMAN:" + system: "GPT:" + assistant: "ASSISTANT:" +template: + # template file ".tmpl" with the prompt template to use by default on the endpoint call. Note there is no extension in the files + completion: completion + chat: ggml-gpt4all-j + edit: edit_template + +# Enable F16 if backend supports it +f16: true +# Enable debugging +debug: true +# Enable embeddings +embeddings: true +# Mirostat configuration (llama.cpp only) +mirostat_eta: 0.8 +mirostat_tau: 0.9 +mirostat: 1 + +# GPU Layers (only used when built with cublas) +gpu_layers: 22 + +# Directory used to store additional assets (used for stablediffusion) +asset_dir: "" +```
### Prompt templates @@ -351,6 +432,8 @@ local-ai --models-path [--address
] [--threads @@ -443,6 +526,48 @@ curl http://localhost:8080/v1/chat/completions -H "Content-Type: application/jso +### Build with Image generation support + +
+ +**Requirements**: OpenCV, Gomp + +Image generation is experimental and requires `GO_TAGS=stablediffusion` to be set during build: + +``` +make GO_TAGS=stablediffusion rebuild +``` + +
+ +### Accelleration + +#### OpenBLAS + +
+ +Requirements: OpenBLAS + +``` +make BUILD_TYPE=openblas build +``` + +
+ +#### CuBLAS + +
+ +Requirement: Nvidia CUDA toolkit + +Note: CuBLAS support is experimental, and has not been tested on real HW. please report any issues you find! + +``` +make BUILD_TYPE=cublas build +``` + +
+ ### Windows compatibility It should work, however you need to make sure you give enough resources to the container. See https://github.com/go-skynet/LocalAI/issues/2 @@ -615,6 +740,77 @@ curl http://localhost:8080/v1/audio/transcriptions -H "Content-Type: multipart/f +### Image generation + +LocalAI supports generating images with Stable diffusion, running on CPU. + +| mode=0 | mode=1 (winograd/sgemm) | +|------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------| +| ![test](https://github.com/go-skynet/LocalAI/assets/2420543/7145bdee-4134-45bb-84d4-f11cb08a5638) | ![b643343452981](https://github.com/go-skynet/LocalAI/assets/2420543/abf14de1-4f50-4715-aaa4-411d703a942a) | +| ![b6441997879](https://github.com/go-skynet/LocalAI/assets/2420543/d50af51c-51b7-4f39-b6c2-bf04c403894c) | ![winograd2](https://github.com/go-skynet/LocalAI/assets/2420543/1935a69a-ecce-4afc-a099-1ac28cb649b3) | +| ![winograd](https://github.com/go-skynet/LocalAI/assets/2420543/1979a8c4-a70d-4602-95ed-642f382f6c6a) | ![winograd3](https://github.com/go-skynet/LocalAI/assets/2420543/e6d184d4-5002-408f-b564-163986e1bdfb) | + +
+ +To generate an image you can send a POST request to the `/v1/images/generations` endpoint with the instruction as the request body: + +```bash +# 512x512 is supported too +curl http://localhost:8080/v1/images/generations -H "Content-Type: application/json" -d '{ + "prompt": "A cute baby sea otter", + "size": "256x256" + }' +``` + +Available additional parameters: `mode`, `step`. + +Note: To set a negative prompt, you can split the prompt with `|`, for instance: `a cute baby sea otter|malformed`. + +```bash +curl http://localhost:8080/v1/images/generations -H "Content-Type: application/json" -d '{ + "prompt": "floating hair, portrait, ((loli)), ((one girl)), cute face, hidden hands, asymmetrical bangs, beautiful detailed eyes, eye shadow, hair ornament, ribbons, bowties, buttons, pleated skirt, (((masterpiece))), ((best quality)), colorful|((part of the head)), ((((mutated hands and fingers)))), deformed, blurry, bad anatomy, disfigured, poorly drawn face, mutation, mutated, extra limb, ugly, poorly drawn hands, missing limb, blurry, floating limbs, disconnected limbs, malformed hands, blur, out of focus, long neck, long body, Octane renderer, lowres, bad anatomy, bad hands, text", + "size": "256x256" + }' +``` + +#### Setup + +Note: In order to use the `images/generation` endpoint, you need to build LocalAI with `GO_TAGS=stablediffusion`. + +1. Create a model file `stablediffusion.yaml` in the models folder: + +```yaml +name: stablediffusion +backend: stablediffusion +asset_dir: stablediffusion_assets +``` +2. Create a `stablediffusion_assets` directory inside your `models` directory +3. Download the ncnn assets from https://github.com/EdVince/Stable-Diffusion-NCNN#out-of-box and place them in `stablediffusion_assets`. + +The models directory should look like the following: + +``` +models +├── stablediffusion_assets +│   ├── AutoencoderKL-256-256-fp16-opt.param +│   ├── AutoencoderKL-512-512-fp16-opt.param +│   ├── AutoencoderKL-base-fp16.param +│   ├── AutoencoderKL-encoder-512-512-fp16.bin +│   ├── AutoencoderKL-fp16.bin +│   ├── FrozenCLIPEmbedder-fp16.bin +│   ├── FrozenCLIPEmbedder-fp16.param +│   ├── log_sigmas.bin +│   ├── tmp-AutoencoderKL-encoder-256-256-fp16.param +│   ├── UNetModel-256-256-MHA-fp16-opt.param +│   ├── UNetModel-512-512-MHA-fp16-opt.param +│   ├── UNetModel-base-MHA-fp16.param +│   ├── UNetModel-MHA-fp16.bin +│   └── vocab.txt +└── stablediffusion.yaml +``` + +
+ ## Frequently asked questions Here are answers to some of the most common questions. @@ -716,10 +912,15 @@ MIT ## Acknowledgements +LocalAI couldn't have been built without the help of great software already available from the community. Thank you! + - [llama.cpp](https://github.com/ggerganov/llama.cpp) - https://github.com/tatsu-lab/stanford_alpaca - https://github.com/cornelk/llama-go for the initial ideas -- https://github.com/antimatter15/alpaca.cpp for the light model version (this is compatible and tested only with that checkpoint model!) +- https://github.com/antimatter15/alpaca.cpp +- https://github.com/EdVince/Stable-Diffusion-NCNN +- https://github.com/ggerganov/whisper.cpp +- https://github.com/saharNooby/rwkv.cpp ## Contributors diff --git a/api/api.go b/api/api.go index 59489f71..ecf56b09 100644 --- a/api/api.go +++ b/api/api.go @@ -12,7 +12,7 @@ import ( "github.com/rs/zerolog/log" ) -func App(configFile string, loader *model.ModelLoader, uploadLimitMB, threads, ctxSize int, f16 bool, debug, disableMessage bool) *fiber.App { +func App(configFile string, loader *model.ModelLoader, uploadLimitMB, threads, ctxSize int, f16 bool, debug, disableMessage bool, imageDir string) *fiber.App { zerolog.SetGlobalLevel(zerolog.InfoLevel) if debug { zerolog.SetGlobalLevel(zerolog.DebugLevel) @@ -87,6 +87,12 @@ func App(configFile string, loader *model.ModelLoader, uploadLimitMB, threads, c app.Post("/v1/audio/transcriptions", transcriptEndpoint(cm, debug, loader, threads, ctxSize, f16)) + app.Post("/v1/images/generations", imageEndpoint(cm, debug, loader, imageDir)) + + if imageDir != "" { + app.Static("/generated-images", imageDir) + } + app.Get("/v1/models", listModels(loader, cm)) app.Get("/models", listModels(loader, cm)) diff --git a/api/api_test.go b/api/api_test.go index a05096df..f2af0388 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -25,7 +25,7 @@ var _ = Describe("API test", func() { Context("API query", func() { BeforeEach(func() { modelLoader = model.NewModelLoader(os.Getenv("MODELS_PATH")) - app = App("", modelLoader, 15, 1, 512, false, true, true) + app = App("", modelLoader, 15, 1, 512, false, true, true, "") go app.Listen("127.0.0.1:9090") defaultConfig := openai.DefaultConfig("") @@ -140,7 +140,7 @@ var _ = Describe("API test", func() { Context("Config file", func() { BeforeEach(func() { modelLoader = model.NewModelLoader(os.Getenv("MODELS_PATH")) - app = App(os.Getenv("CONFIG_FILE"), modelLoader, 5, 1, 512, false, true, true) + app = App(os.Getenv("CONFIG_FILE"), modelLoader, 5, 1, 512, false, true, true, "") go app.Listen("127.0.0.1:9090") defaultConfig := openai.DefaultConfig("") diff --git a/api/config.go b/api/config.go index 3791d490..7379978e 100644 --- a/api/config.go +++ b/api/config.go @@ -32,6 +32,7 @@ type Config struct { MirostatTAU float64 `yaml:"mirostat_tau"` Mirostat int `yaml:"mirostat"` NGPULayers int `yaml:"gpu_layers"` + ImageGenerationAssets string `yaml:"asset_dir"` PromptStrings, InputStrings []string InputToken [][]int } @@ -211,12 +212,11 @@ func updateConfig(config *Config, input *OpenAIRequest) { } } } - -func readConfig(cm ConfigMerger, c *fiber.Ctx, loader *model.ModelLoader, debug bool, threads, ctx int, f16 bool) (*Config, *OpenAIRequest, error) { +func readInput(c *fiber.Ctx, loader *model.ModelLoader, randomModel bool) (string, *OpenAIRequest, error) { input := new(OpenAIRequest) // Get input data from the request body if err := c.BodyParser(input); err != nil { - return nil, nil, err + return "", nil, err } modelFile := input.Model @@ -234,14 +234,14 @@ func readConfig(cm ConfigMerger, c *fiber.Ctx, loader *model.ModelLoader, debug bearerExists := bearer != "" && loader.ExistsInModelPath(bearer) // If no model was specified, take the first available - if modelFile == "" && !bearerExists { + if modelFile == "" && !bearerExists && randomModel { models, _ := loader.ListModels() if len(models) > 0 { modelFile = models[0] log.Debug().Msgf("No model specified, using: %s", modelFile) } else { log.Debug().Msgf("No model specified, returning error") - return nil, nil, fmt.Errorf("no model specified") + return "", nil, fmt.Errorf("no model specified") } } @@ -250,7 +250,10 @@ func readConfig(cm ConfigMerger, c *fiber.Ctx, loader *model.ModelLoader, debug log.Debug().Msgf("Using model from bearer token: %s", bearer) modelFile = bearer } + return modelFile, input, nil +} +func readConfig(modelFile string, input *OpenAIRequest, cm ConfigMerger, loader *model.ModelLoader, debug bool, threads, ctx int, f16 bool) (*Config, *OpenAIRequest, error) { // Load a config file if present after the model name modelConfig := filepath.Join(loader.ModelPath, modelFile+".yaml") if _, err := os.Stat(modelConfig); err == nil { diff --git a/api/openai.go b/api/openai.go index 7b651353..19284f24 100644 --- a/api/openai.go +++ b/api/openai.go @@ -3,13 +3,16 @@ package api import ( "bufio" "bytes" + "encoding/base64" "encoding/json" "fmt" "io" + "io/ioutil" "net/http" "os" "path" "path/filepath" + "strconv" "strings" "github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper" @@ -43,6 +46,10 @@ type Item struct { Embedding []float32 `json:"embedding"` Index int `json:"index"` Object string `json:"object,omitempty"` + + // Images + URL string `json:"url,omitempty"` + B64JSON string `json:"b64_json,omitempty"` } type OpenAIResponse struct { @@ -78,11 +85,13 @@ type OpenAIRequest struct { Model string `json:"model" yaml:"model"` // whisper - File string `json:"file" validate:"required"` + File string `json:"file" validate:"required"` + Language string `json:"language"` + //whisper/image ResponseFormat string `json:"response_format"` - Language string `json:"language"` - - // Prompt is read only by completion API calls + // image + Size string `json:"size"` + // Prompt is read only by completion/image API calls Prompt interface{} `json:"prompt" yaml:"prompt"` // Edit endpoint @@ -116,6 +125,10 @@ type OpenAIRequest struct { Mirostat int `json:"mirostat" yaml:"mirostat"` Seed int `json:"seed" yaml:"seed"` + + // Image (not supported by OpenAI) + Mode int `json:"mode"` + Step int `json:"step"` } func defaultRequest(modelFile string) OpenAIRequest { @@ -131,7 +144,13 @@ func defaultRequest(modelFile string) OpenAIRequest { // https://platform.openai.com/docs/api-reference/completions func completionEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, threads, ctx int, f16 bool) func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { - config, input, err := readConfig(cm, c, loader, debug, threads, ctx, f16) + + model, input, err := readInput(c, loader, true) + if err != nil { + return fmt.Errorf("failed reading parameters from request:%w", err) + } + + config, input, err := readConfig(model, input, cm, loader, debug, threads, ctx, f16) if err != nil { return fmt.Errorf("failed reading parameters from request:%w", err) } @@ -182,7 +201,12 @@ func completionEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, // https://platform.openai.com/docs/api-reference/embeddings func embeddingsEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, threads, ctx int, f16 bool) func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { - config, input, err := readConfig(cm, c, loader, debug, threads, ctx, f16) + model, input, err := readInput(c, loader, true) + if err != nil { + return fmt.Errorf("failed reading parameters from request:%w", err) + } + + config, input, err := readConfig(model, input, cm, loader, debug, threads, ctx, f16) if err != nil { return fmt.Errorf("failed reading parameters from request:%w", err) } @@ -249,7 +273,12 @@ func chatEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, thread close(responses) } return func(c *fiber.Ctx) error { - config, input, err := readConfig(cm, c, loader, debug, threads, ctx, f16) + model, input, err := readInput(c, loader, true) + if err != nil { + return fmt.Errorf("failed reading parameters from request:%w", err) + } + + config, input, err := readConfig(model, input, cm, loader, debug, threads, ctx, f16) if err != nil { return fmt.Errorf("failed reading parameters from request:%w", err) } @@ -349,7 +378,12 @@ func chatEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, thread func editEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, threads, ctx int, f16 bool) func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { - config, input, err := readConfig(cm, c, loader, debug, threads, ctx, f16) + model, input, err := readInput(c, loader, true) + if err != nil { + return fmt.Errorf("failed reading parameters from request:%w", err) + } + + config, input, err := readConfig(model, input, cm, loader, debug, threads, ctx, f16) if err != nil { return fmt.Errorf("failed reading parameters from request:%w", err) } @@ -398,14 +432,151 @@ func editEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, thread } } -// https://platform.openai.com/docs/api-reference/audio/create -func transcriptEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, threads, ctx int, f16 bool) func(c *fiber.Ctx) error { +// https://platform.openai.com/docs/api-reference/images/create + +/* +* + + curl http://localhost:8080/v1/images/generations \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "A cute baby sea otter", + "n": 1, + "size": "512x512" + }' + +* +*/ +func imageEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, imageDir string) func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error { - config, input, err := readConfig(cm, c, loader, debug, threads, ctx, f16) + m, input, err := readInput(c, loader, false) if err != nil { return fmt.Errorf("failed reading parameters from request:%w", err) } + if m == "" { + m = model.StableDiffusionBackend + } + log.Debug().Msgf("Loading model: %+v", m) + + config, input, err := readConfig(m, input, cm, loader, debug, 0, 0, false) + if err != nil { + return fmt.Errorf("failed reading parameters from request:%w", err) + } + + log.Debug().Msgf("Parameter Config: %+v", config) + + // XXX: Only stablediffusion is supported for now + if config.Backend == "" { + config.Backend = model.StableDiffusionBackend + } + + sizeParts := strings.Split(input.Size, "x") + if len(sizeParts) != 2 { + return fmt.Errorf("Invalid value for 'size'") + } + width, err := strconv.Atoi(sizeParts[0]) + if err != nil { + return fmt.Errorf("Invalid value for 'size'") + } + height, err := strconv.Atoi(sizeParts[1]) + if err != nil { + return fmt.Errorf("Invalid value for 'size'") + } + + b64JSON := false + if input.ResponseFormat == "b64_json" { + b64JSON = true + } + + var result []Item + for _, i := range config.PromptStrings { + prompts := strings.Split(i, "|") + positive_prompt := prompts[0] + negative_prompt := "" + if len(prompts) > 1 { + negative_prompt = prompts[1] + } + + mode := 0 + step := 15 + + if input.Mode != 0 { + mode = input.Mode + } + + if input.Step != 0 { + step = input.Step + } + + tempDir := "" + if !b64JSON { + tempDir = imageDir + } + // Create a temporary file + outputFile, err := ioutil.TempFile(tempDir, "b64") + if err != nil { + return err + } + outputFile.Close() + output := outputFile.Name() + ".png" + // Rename the temporary file + err = os.Rename(outputFile.Name(), output) + if err != nil { + return err + } + + baseURL := c.BaseURL() + + fn, err := ImageGeneration(height, width, mode, step, input.Seed, positive_prompt, negative_prompt, output, loader, *config) + if err != nil { + return err + } + if err := fn(); err != nil { + return err + } + + item := &Item{} + + if b64JSON { + defer os.RemoveAll(output) + data, err := os.ReadFile(output) + if err != nil { + return err + } + item.B64JSON = base64.StdEncoding.EncodeToString(data) + } else { + base := filepath.Base(output) + item.URL = baseURL + "/generated-images/" + base + } + + result = append(result, *item) + } + + resp := &OpenAIResponse{ + Data: result, + } + + jsonResult, _ := json.Marshal(resp) + log.Debug().Msgf("Response: %s", jsonResult) + + // Return the prediction in the response body + return c.JSON(resp) + } +} + +// https://platform.openai.com/docs/api-reference/audio/create +func transcriptEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, threads, ctx int, f16 bool) func(c *fiber.Ctx) error { + return func(c *fiber.Ctx) error { + m, input, err := readInput(c, loader, false) + if err != nil { + return fmt.Errorf("failed reading parameters from request:%w", err) + } + + config, input, err := readConfig(m, input, cm, loader, debug, threads, ctx, f16) + if err != nil { + return fmt.Errorf("failed reading parameters from request:%w", err) + } // retrieve the file data from the request file, err := c.FormFile("file") if err != nil { diff --git a/api/prediction.go b/api/prediction.go index 7aa839bb..c279e08d 100644 --- a/api/prediction.go +++ b/api/prediction.go @@ -8,11 +8,12 @@ import ( "github.com/donomii/go-rwkv.cpp" model "github.com/go-skynet/LocalAI/pkg/model" + "github.com/go-skynet/LocalAI/pkg/stablediffusion" "github.com/go-skynet/bloomz.cpp" bert "github.com/go-skynet/go-bert.cpp" gpt2 "github.com/go-skynet/go-gpt2.cpp" llama "github.com/go-skynet/go-llama.cpp" - gpt4all "github.com/nomic/gpt4all/gpt4all-bindings/golang" + gpt4all "github.com/nomic-ai/gpt4all/gpt4all-bindings/golang" ) // mutex still needed, see: https://github.com/ggerganov/llama.cpp/discussions/784 @@ -38,6 +39,45 @@ func defaultLLamaOpts(c Config) []llama.ModelOption { return llamaOpts } +func ImageGeneration(height, width, mode, step, seed int, positive_prompt, negative_prompt, dst string, loader *model.ModelLoader, c Config) (func() error, error) { + if c.Backend != model.StableDiffusionBackend { + return nil, fmt.Errorf("endpoint only working with stablediffusion models") + } + inferenceModel, err := loader.BackendLoader(c.Backend, c.ImageGenerationAssets, []llama.ModelOption{}, uint32(c.Threads)) + if err != nil { + return nil, err + } + + var fn func() error + switch model := inferenceModel.(type) { + case *stablediffusion.StableDiffusion: + fn = func() error { + return model.GenerateImage(height, width, mode, step, seed, positive_prompt, negative_prompt, dst) + } + + default: + fn = func() error { + return fmt.Errorf("creation of images not supported by the backend") + } + } + + return func() error { + // This is still needed, see: https://github.com/ggerganov/llama.cpp/discussions/784 + mutexMap.Lock() + l, ok := mutexes[c.Backend] + if !ok { + m := &sync.Mutex{} + mutexes[c.Backend] = m + l = m + } + mutexMap.Unlock() + l.Lock() + defer l.Unlock() + + return fn() + }, nil +} + func ModelEmbedding(s string, tokens []int, loader *model.ModelLoader, c Config) (func() ([]float32, error), error) { if !c.Embeddings { return nil, fmt.Errorf("endpoint disabled for this model by API configuration") diff --git a/examples/chatbot-ui/README.md b/examples/chatbot-ui/README.md index 93459bcc..7cf4bbb2 100644 --- a/examples/chatbot-ui/README.md +++ b/examples/chatbot-ui/README.md @@ -19,7 +19,9 @@ cd LocalAI/examples/chatbot-ui wget https://gpt4all.io/models/ggml-gpt4all-j.bin -O models/ggml-gpt4all-j # start with docker-compose -docker-compose up -d --build +docker-compose up -d --pull always +# or you can build the images with: +# docker-compose up -d --build ``` ## Pointing chatbot-ui to a separately managed LocalAI service diff --git a/go.mod b/go.mod index 64b2a9de..8ff80844 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,8 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/nomic/gpt4all/gpt4all-bindings/golang v0.0.0-00010101000000-000000000000 // indirect + github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24 // indirect + github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc // indirect github.com/philhofer/fwd v1.1.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 0fdfd9b3..b1a1a93a 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,12 @@ github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp9 github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24 h1:XfRD/bZom6u4zji7aB0urIVOsPe43KlkzSRrVhlzaOM= +github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24/go.mod h1:8ufRkpz/S/9ahkaxzZ5i4WMgO9w4InEhuRoT7vK5Rnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc h1:OPavP/SUsVWVYPhSUZKZeX8yDSQzf4G+BmUmwzrLTyI= +github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc/go.mod h1:4T3CHXyrt+7FQHXaxULZfPjHbD8/99WuDDJa0YVZARI= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= diff --git a/main.go b/main.go index 275fb318..2490e198 100644 --- a/main.go +++ b/main.go @@ -56,6 +56,12 @@ func main() { EnvVars: []string{"ADDRESS"}, Value: ":8080", }, + &cli.StringFlag{ + Name: "image-dir", + DefaultText: "Image directory", + EnvVars: []string{"IMAGE_DIR"}, + Value: "", + }, &cli.IntFlag{ Name: "context-size", DefaultText: "Default context size of the model", @@ -87,7 +93,7 @@ It uses llama.cpp, ggml and gpt4all as backend with golang c bindings. Copyright: "go-skynet authors", Action: func(ctx *cli.Context) error { fmt.Printf("Starting LocalAI using %d threads, with models path: %s\n", ctx.Int("threads"), ctx.String("models-path")) - return api.App(ctx.String("config-file"), model.NewModelLoader(ctx.String("models-path")), ctx.Int("upload-limit"), ctx.Int("threads"), ctx.Int("context-size"), ctx.Bool("f16"), ctx.Bool("debug"), false).Listen(ctx.String("address")) + return api.App(ctx.String("config-file"), model.NewModelLoader(ctx.String("models-path")), ctx.Int("upload-limit"), ctx.Int("threads"), ctx.Int("context-size"), ctx.Bool("f16"), ctx.Bool("debug"), false, ctx.String("image-dir")).Listen(ctx.String("address")) }, } diff --git a/pkg/model/initializers.go b/pkg/model/initializers.go index ab5a9af5..74c05f29 100644 --- a/pkg/model/initializers.go +++ b/pkg/model/initializers.go @@ -7,33 +7,35 @@ import ( rwkv "github.com/donomii/go-rwkv.cpp" whisper "github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper" + "github.com/go-skynet/LocalAI/pkg/stablediffusion" bloomz "github.com/go-skynet/bloomz.cpp" bert "github.com/go-skynet/go-bert.cpp" gpt2 "github.com/go-skynet/go-gpt2.cpp" llama "github.com/go-skynet/go-llama.cpp" "github.com/hashicorp/go-multierror" - gpt4all "github.com/nomic/gpt4all/gpt4all-bindings/golang" + gpt4all "github.com/nomic-ai/gpt4all/gpt4all-bindings/golang" "github.com/rs/zerolog/log" ) const tokenizerSuffix = ".tokenizer.json" const ( - LlamaBackend = "llama" - BloomzBackend = "bloomz" - StarcoderBackend = "starcoder" - StableLMBackend = "stablelm" - DollyBackend = "dolly" - RedPajamaBackend = "redpajama" - GPTNeoXBackend = "gptneox" - ReplitBackend = "replit" - Gpt2Backend = "gpt2" - Gpt4AllLlamaBackend = "gpt4all-llama" - Gpt4AllMptBackend = "gpt4all-mpt" - Gpt4AllJBackend = "gpt4all-j" - BertEmbeddingsBackend = "bert-embeddings" - RwkvBackend = "rwkv" - WhisperBackend = "whisper" + LlamaBackend = "llama" + BloomzBackend = "bloomz" + StarcoderBackend = "starcoder" + StableLMBackend = "stablelm" + DollyBackend = "dolly" + RedPajamaBackend = "redpajama" + GPTNeoXBackend = "gptneox" + ReplitBackend = "replit" + Gpt2Backend = "gpt2" + Gpt4AllLlamaBackend = "gpt4all-llama" + Gpt4AllMptBackend = "gpt4all-mpt" + Gpt4AllJBackend = "gpt4all-j" + BertEmbeddingsBackend = "bert-embeddings" + RwkvBackend = "rwkv" + WhisperBackend = "whisper" + StableDiffusionBackend = "stablediffusion" ) var backends []string = []string{ @@ -48,8 +50,8 @@ var backends []string = []string{ StableLMBackend, DollyBackend, RedPajamaBackend, - GPTNeoXBackend, ReplitBackend, + GPTNeoXBackend, BertEmbeddingsBackend, StarcoderBackend, } @@ -89,6 +91,10 @@ var gpt2LM = func(modelFile string) (interface{}, error) { return gpt2.New(modelFile) } +var stableDiffusion = func(assetDir string) (interface{}, error) { + return stablediffusion.New(assetDir) +} + var whisperModel = func(modelFile string) (interface{}, error) { return whisper.New(modelFile) } @@ -107,6 +113,8 @@ func gpt4allLM(opts ...gpt4all.ModelOption) func(string) (interface{}, error) { func rwkvLM(tokenFile string, threads uint32) func(string) (interface{}, error) { return func(s string) (interface{}, error) { + log.Debug().Msgf("Loading RWKV", s, tokenFile) + model := rwkv.LoadFiles(s, tokenFile, threads) if model == nil { return nil, fmt.Errorf("could not load model") @@ -116,6 +124,7 @@ func rwkvLM(tokenFile string, threads uint32) func(string) (interface{}, error) } func (ml *ModelLoader) BackendLoader(backendString string, modelFile string, llamaOpts []llama.ModelOption, threads uint32) (model interface{}, err error) { + log.Debug().Msgf("Loading model %s from %s", backendString, modelFile) switch strings.ToLower(backendString) { case LlamaBackend: return ml.LoadModel(modelFile, llamaLM(llamaOpts...)) @@ -133,6 +142,8 @@ func (ml *ModelLoader) BackendLoader(backendString string, modelFile string, lla return ml.LoadModel(modelFile, gptNeoX) case ReplitBackend: return ml.LoadModel(modelFile, replit) + case StableDiffusionBackend: + return ml.LoadModel(modelFile, stableDiffusion) case StarcoderBackend: return ml.LoadModel(modelFile, starCoder) case Gpt4AllLlamaBackend: diff --git a/pkg/stablediffusion/generate.go b/pkg/stablediffusion/generate.go new file mode 100644 index 00000000..97989e90 --- /dev/null +++ b/pkg/stablediffusion/generate.go @@ -0,0 +1,23 @@ +//go:build stablediffusion +// +build stablediffusion + +package stablediffusion + +import ( + stableDiffusion "github.com/mudler/go-stable-diffusion" +) + +func GenerateImage(height, width, mode, step, seed int, positive_prompt, negative_prompt, dst, asset_dir string) error { + return stableDiffusion.GenerateImage( + height, + width, + mode, + step, + seed, + positive_prompt, + negative_prompt, + dst, + "", + asset_dir, + ) +} diff --git a/pkg/stablediffusion/generate_unsupported.go b/pkg/stablediffusion/generate_unsupported.go new file mode 100644 index 00000000..9563bae0 --- /dev/null +++ b/pkg/stablediffusion/generate_unsupported.go @@ -0,0 +1,10 @@ +//go:build !stablediffusion +// +build !stablediffusion + +package stablediffusion + +import "fmt" + +func GenerateImage(height, width, mode, step, seed int, positive_prompt, negative_prompt, dst, asset_dir string) error { + return fmt.Errorf("This version of LocalAI was built without the stablediffusion tag") +} diff --git a/pkg/stablediffusion/stablediffusion.go b/pkg/stablediffusion/stablediffusion.go new file mode 100644 index 00000000..e38db17f --- /dev/null +++ b/pkg/stablediffusion/stablediffusion.go @@ -0,0 +1,20 @@ +package stablediffusion + +import "os" + +type StableDiffusion struct { + assetDir string +} + +func New(assetDir string) (*StableDiffusion, error) { + if _, err := os.Stat(assetDir); err != nil { + return nil, err + } + return &StableDiffusion{ + assetDir: assetDir, + }, nil +} + +func (s *StableDiffusion) GenerateImage(height, width, mode, step, seed int, positive_prompt, negative_prompt, dst string) error { + return GenerateImage(height, width, mode, step, seed, positive_prompt, negative_prompt, dst, s.assetDir) +} From 9237c1e91da93f313536a6e3b33d49388b21da66 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 22:34:36 +0200 Subject: [PATCH 03/18] fix(deps): update github.com/ggerganov/whisper.cpp/bindings/go digest to 95b02d7 (#254) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8ff80844..a620afac 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/donomii/go-rwkv.cpp v0.0.0-20230510174014-07166da10cb2 - github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230509153812-1d17cd5bb37a + github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230515153606-95b02d76b04d github.com/go-audio/wav v1.1.0 github.com/go-skynet/bloomz.cpp v0.0.0-20230510195113-ad7e89a0885f github.com/go-skynet/go-bert.cpp v0.0.0-20230510124618-ec771ec71557 @@ -13,6 +13,8 @@ require ( github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b github.com/gofiber/fiber/v2 v2.45.0 github.com/hashicorp/go-multierror v1.1.1 + github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24 + github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc github.com/onsi/ginkgo/v2 v2.9.4 github.com/onsi/gomega v1.27.6 github.com/otiai10/copy v1.11.0 @@ -49,8 +51,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24 // indirect - github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc // indirect github.com/philhofer/fwd v1.1.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index b1a1a93a..2f834751 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230508180809-bf2449dfae35 github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230508180809-bf2449dfae35/go.mod h1:QIjZ9OktHFG7p+/m3sMvrAJKKdWrr1fZIK0rM6HZlyo= github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230509153812-1d17cd5bb37a h1:MlyiDLNCM/wjbv8U5Elj18NvaAgl61SGiRUpqQz5dfs= github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230509153812-1d17cd5bb37a/go.mod h1:QIjZ9OktHFG7p+/m3sMvrAJKKdWrr1fZIK0rM6HZlyo= +github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230515153606-95b02d76b04d h1:uxKTbiRnplE2SubchneSf4NChtxLJtOy9VdHnQMT0d0= +github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230515153606-95b02d76b04d/go.mod h1:QIjZ9OktHFG7p+/m3sMvrAJKKdWrr1fZIK0rM6HZlyo= github.com/go-audio/audio v1.0.0 h1:zS9vebldgbQqktK4H0lUqWrG8P0NxCJVqcj7ZpNnwd4= github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= github.com/go-audio/riff v1.0.0 h1:d8iCGbDvox9BfLagY94fBynxSPHO80LmZCaOsmKxokA= From 63a4ccebdcb431b34fe31e04b81fd5810c3c1386 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 01:03:43 +0200 Subject: [PATCH 04/18] fix(deps): update module github.com/onsi/ginkgo/v2 to v2.9.5 (#264) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a620afac..25ce3559 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24 github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc - github.com/onsi/ginkgo/v2 v2.9.4 + github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 github.com/otiai10/copy v1.11.0 github.com/otiai10/openaigo v1.1.0 @@ -60,9 +60,9 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/net v0.9.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.8.0 // indirect + golang.org/x/tools v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 2f834751..3c3f4744 100644 --- a/go.sum +++ b/go.sum @@ -103,6 +103,8 @@ github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d624 github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc/go.mod h1:4T3CHXyrt+7FQHXaxULZfPjHbD8/99WuDDJa0YVZARI= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= +github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc= @@ -170,6 +172,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -207,6 +211,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 41de6efca92e3ee9aec058b9ab8f9d97a5f807a8 Mon Sep 17 00:00:00 2001 From: "ci-robbot [bot]" <105103991+ci-robbot@users.noreply.github.com> Date: Wed, 17 May 2023 01:04:14 +0200 Subject: [PATCH 05/18] :arrow_up: Update ggerganov/whisper.cpp (#265) Signed-off-by: GitHub Co-authored-by: mudler --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dec3569a..804af85d 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GPT4ALL_VERSION?=a07237e54fcdfdb351913587052ac061a2a7bdff GOGPT2_VERSION?=92421a8cf61ed6e03babd9067af292b094cb1307 RWKV_REPO?=https://github.com/donomii/go-rwkv.cpp RWKV_VERSION?=07166da10cb2a9e8854395a4f210464dcea76e47 -WHISPER_CPP_VERSION?=a5defbc1b98bea0f070331ce1e8b62d947b0443d +WHISPER_CPP_VERSION?=95b02d76b04d18e4ce37ed8353a1f0797f1717ea BERT_VERSION?=33118e0da50318101408986b86a331daeb4a6658 BLOOMZ_VERSION?=e9366e82abdfe70565644fbfae9651976714efd1 BUILD_TYPE?= From cdca286be151d7f836ee0b48ae8a770bd78f264b Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Wed, 17 May 2023 01:30:30 +0200 Subject: [PATCH 06/18] docker: add openblas and opencv to images (#277) --- Dockerfile | 3 ++- Dockerfile.dev | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b82850a9..52869bb9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,8 +2,9 @@ ARG GO_VERSION=1.20 ARG BUILD_TYPE= FROM golang:$GO_VERSION WORKDIR /build -RUN apt-get update && apt-get install -y cmake +RUN apt-get update && apt-get install -y cmake libgomp1 libopenblas-dev libopenblas-base libopencv-dev libopencv-core-dev libopencv-core4.5 COPY . . +RUN ln -s /usr/include/opencv4/opencv2/ /usr/include/opencv2 RUN make prepare-sources EXPOSE 8080 ENTRYPOINT [ "/build/entrypoint.sh" ] diff --git a/Dockerfile.dev b/Dockerfile.dev index 16c84476..50b15944 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -4,7 +4,8 @@ ARG BUILD_TYPE= FROM golang:$GO_VERSION as builder WORKDIR /build -RUN apt-get update && apt-get install -y cmake +RUN apt-get update && apt-get install -y cmake libgomp1 libopenblas-dev libopenblas-base libopencv-dev libopencv-core-dev libopencv-core4.5 +RUN ln -s /usr/include/opencv4/opencv2/ /usr/include/opencv2 COPY . . RUN make build From c2026e01c049fc769c1a6952bedc075da76662ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 01:44:14 +0200 Subject: [PATCH 07/18] fix(deps): update github.com/mudler/go-stable-diffusion digest to c0748ec (#275) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 25ce3559..66b3d845 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b github.com/gofiber/fiber/v2 v2.45.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24 + github.com/mudler/go-stable-diffusion v0.0.0-20230516152536-c0748eca3642 github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc github.com/onsi/ginkgo/v2 v2.9.5 github.com/onsi/gomega v1.27.6 diff --git a/go.sum b/go.sum index 3c3f4744..38800516 100644 --- a/go.sum +++ b/go.sum @@ -97,6 +97,8 @@ github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWV github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24 h1:XfRD/bZom6u4zji7aB0urIVOsPe43KlkzSRrVhlzaOM= github.com/mudler/go-stable-diffusion v0.0.0-20230516104333-2f32a16b5b24/go.mod h1:8ufRkpz/S/9ahkaxzZ5i4WMgO9w4InEhuRoT7vK5Rnw= +github.com/mudler/go-stable-diffusion v0.0.0-20230516152536-c0748eca3642 h1:KTkh3lOUsGqQyP4v+oa38sPFdrZtNnM4HaxTb3epdYs= +github.com/mudler/go-stable-diffusion v0.0.0-20230516152536-c0748eca3642/go.mod h1:8ufRkpz/S/9ahkaxzZ5i4WMgO9w4InEhuRoT7vK5Rnw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nomic-ai/gpt4all/gpt4all-bindings/golang v0.0.0-20230516143155-79d6243fe1bc h1:OPavP/SUsVWVYPhSUZKZeX8yDSQzf4G+BmUmwzrLTyI= From 76be06ed56b01ac7cb2881f20c2e4f4a353c5e85 Mon Sep 17 00:00:00 2001 From: "ci-robbot [bot]" <105103991+ci-robbot@users.noreply.github.com> Date: Wed, 17 May 2023 01:47:31 +0200 Subject: [PATCH 08/18] :arrow_up: Update go-skynet/go-gpt2.cpp (#253) Signed-off-by: GitHub Co-authored-by: mudler --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 804af85d..9a3debe7 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ BINARY_NAME=local-ai GOLLAMA_VERSION?=7f9ae4246088f0c08ed322acbae21d69cd2eb547 GPT4ALL_REPO?=https://github.com/nomic-ai/gpt4all GPT4ALL_VERSION?=a07237e54fcdfdb351913587052ac061a2a7bdff -GOGPT2_VERSION?=92421a8cf61ed6e03babd9067af292b094cb1307 +GOGPT2_VERSION?=7bff56f0224502c1c9ed6258d2a17e8084628827 RWKV_REPO?=https://github.com/donomii/go-rwkv.cpp RWKV_VERSION?=07166da10cb2a9e8854395a4f210464dcea76e47 WHISPER_CPP_VERSION?=95b02d76b04d18e4ce37ed8353a1f0797f1717ea From cd81dbae1c5119aba81246ac0c3098c4536cc544 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 08:17:05 +0200 Subject: [PATCH 09/18] fix(deps): update github.com/go-skynet/bloomz.cpp digest to e9366e8 (#227) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 66b3d845..9f4ce16c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/donomii/go-rwkv.cpp v0.0.0-20230510174014-07166da10cb2 github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230515153606-95b02d76b04d github.com/go-audio/wav v1.1.0 - github.com/go-skynet/bloomz.cpp v0.0.0-20230510195113-ad7e89a0885f + github.com/go-skynet/bloomz.cpp v0.0.0-20230510223001-e9366e82abdf github.com/go-skynet/go-bert.cpp v0.0.0-20230510124618-ec771ec71557 github.com/go-skynet/go-gpt2.cpp v0.0.0-20230509180201-d49823284cc6 github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c diff --git a/go.sum b/go.sum index 38800516..01253c41 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,8 @@ github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyr github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-skynet/bloomz.cpp v0.0.0-20230510195113-ad7e89a0885f h1:GW8RQa1RVeDF1dOuAP/y6xWVC+BRtf9tJOuEza6Asbg= github.com/go-skynet/bloomz.cpp v0.0.0-20230510195113-ad7e89a0885f/go.mod h1:wc0fJ9V04yiYTfgKvE5RUUSRQ5Kzi0Bo4I+U3nNOUuA= +github.com/go-skynet/bloomz.cpp v0.0.0-20230510223001-e9366e82abdf h1:VJfSn8hIDE+K5+h38M3iAyFXrxpRExMKRdTk33UDxsw= +github.com/go-skynet/bloomz.cpp v0.0.0-20230510223001-e9366e82abdf/go.mod h1:wc0fJ9V04yiYTfgKvE5RUUSRQ5Kzi0Bo4I+U3nNOUuA= github.com/go-skynet/go-bert.cpp v0.0.0-20230510101404-7bb183b147ea h1:8Isk9D+Auth5OuXVAQPC3MO+5zF/2S7mvs2JZLw6a+8= github.com/go-skynet/go-bert.cpp v0.0.0-20230510101404-7bb183b147ea/go.mod h1:NHwIVvsg7Jh6p0M4uBLVmSMEaPUia6O6yjXUpLWVJmQ= github.com/go-skynet/go-bert.cpp v0.0.0-20230510124618-ec771ec71557 h1:LD66fKtvP2lmyuuKL8pBat/pVTKUbLs3L5fM/5lyi4w= From 17b18df600854bc1061cb9276c61cc856107c3c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 08:54:52 +0200 Subject: [PATCH 10/18] fix(deps): update github.com/donomii/go-rwkv.cpp digest to 6fdd0c3 (#240) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 9f4ce16c..7e29eb73 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/go-skynet/LocalAI go 1.19 require ( - github.com/donomii/go-rwkv.cpp v0.0.0-20230510174014-07166da10cb2 + github.com/donomii/go-rwkv.cpp v0.0.0-20230515123100-6fdd0c338e56 github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230515153606-95b02d76b04d github.com/go-audio/wav v1.1.0 github.com/go-skynet/bloomz.cpp v0.0.0-20230510223001-e9366e82abdf diff --git a/go.sum b/go.sum index 01253c41..1941edc8 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/donomii/go-rwkv.cpp v0.0.0-20230503112711-af62fcc432be h1:3Hic97PY6hc github.com/donomii/go-rwkv.cpp v0.0.0-20230503112711-af62fcc432be/go.mod h1:gWy7FIWioqYmYxkaoFyBnaKApeZVrUkHhv9EV9pz4dM= github.com/donomii/go-rwkv.cpp v0.0.0-20230510174014-07166da10cb2 h1:YNbUAyIRtaLODitigJU1EM5ubmMu5FmHtYAayJD6Vbg= github.com/donomii/go-rwkv.cpp v0.0.0-20230510174014-07166da10cb2/go.mod h1:gWy7FIWioqYmYxkaoFyBnaKApeZVrUkHhv9EV9pz4dM= +github.com/donomii/go-rwkv.cpp v0.0.0-20230515123100-6fdd0c338e56 h1:s8/MZdicstKi5fn9D9mKGIQ/q6IWCYCk/BM68i8v51w= +github.com/donomii/go-rwkv.cpp v0.0.0-20230515123100-6fdd0c338e56/go.mod h1:gWy7FIWioqYmYxkaoFyBnaKApeZVrUkHhv9EV9pz4dM= github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230508180809-bf2449dfae35 h1:sMg/SgnMPS/HNUO/2kGm72vl8R9TmNIwgLFr2TNwR3g= github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230508180809-bf2449dfae35/go.mod h1:QIjZ9OktHFG7p+/m3sMvrAJKKdWrr1fZIK0rM6HZlyo= github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230509153812-1d17cd5bb37a h1:MlyiDLNCM/wjbv8U5Elj18NvaAgl61SGiRUpqQz5dfs= From 1428600de404ca1af167c9fee7a4100bccb6557d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 09:47:22 +0200 Subject: [PATCH 11/18] fix(deps): update github.com/go-skynet/go-bert.cpp digest to cea1ed7 (#242) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7e29eb73..41b59b2c 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20230515153606-95b02d76b04d github.com/go-audio/wav v1.1.0 github.com/go-skynet/bloomz.cpp v0.0.0-20230510223001-e9366e82abdf - github.com/go-skynet/go-bert.cpp v0.0.0-20230510124618-ec771ec71557 + github.com/go-skynet/go-bert.cpp v0.0.0-20230516063724-cea1ed76a7f4 github.com/go-skynet/go-gpt2.cpp v0.0.0-20230509180201-d49823284cc6 github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b diff --git a/go.sum b/go.sum index 1941edc8..79607cfd 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/go-skynet/go-bert.cpp v0.0.0-20230510101404-7bb183b147ea h1:8Isk9D+Au github.com/go-skynet/go-bert.cpp v0.0.0-20230510101404-7bb183b147ea/go.mod h1:NHwIVvsg7Jh6p0M4uBLVmSMEaPUia6O6yjXUpLWVJmQ= github.com/go-skynet/go-bert.cpp v0.0.0-20230510124618-ec771ec71557 h1:LD66fKtvP2lmyuuKL8pBat/pVTKUbLs3L5fM/5lyi4w= github.com/go-skynet/go-bert.cpp v0.0.0-20230510124618-ec771ec71557/go.mod h1:NHwIVvsg7Jh6p0M4uBLVmSMEaPUia6O6yjXUpLWVJmQ= +github.com/go-skynet/go-bert.cpp v0.0.0-20230516063724-cea1ed76a7f4 h1:+3KPDf4Wv1VHOkzAfZnlj9qakLSYggTpm80AswhD/FU= +github.com/go-skynet/go-bert.cpp v0.0.0-20230516063724-cea1ed76a7f4/go.mod h1:VY0s5KoAI2jRCvQXKuDeEEe8KG7VaWifSNJSk+E1KtY= github.com/go-skynet/go-gpt2.cpp v0.0.0-20230509180201-d49823284cc6 h1:XshpypO6ekU09CI19vuzke2a1Es1lV5ZaxA7CUehu0E= github.com/go-skynet/go-gpt2.cpp v0.0.0-20230509180201-d49823284cc6/go.mod h1:1Wj/xbkMfwQSOrhNYK178IzqQHstZbRfhx4s8p1M5VM= github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c h1:48I7jpLNGiQeBmF0SFVVbREh8vlG0zN13v9LH5ctXis= From d096644c67c67e92db0273bf0fbb5d5c1b9bdfe3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 11:52:37 +0200 Subject: [PATCH 12/18] fix(deps): update github.com/go-skynet/go-gpt2.cpp digest to 7bff56f (#217) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 41b59b2c..b2940b5d 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-audio/wav v1.1.0 github.com/go-skynet/bloomz.cpp v0.0.0-20230510223001-e9366e82abdf github.com/go-skynet/go-bert.cpp v0.0.0-20230516063724-cea1ed76a7f4 - github.com/go-skynet/go-gpt2.cpp v0.0.0-20230509180201-d49823284cc6 + github.com/go-skynet/go-gpt2.cpp v0.0.0-20230512145559-7bff56f02245 github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b github.com/gofiber/fiber/v2 v2.45.0 diff --git a/go.sum b/go.sum index 79607cfd..bbda762c 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,8 @@ github.com/go-skynet/go-bert.cpp v0.0.0-20230516063724-cea1ed76a7f4 h1:+3KPDf4Wv github.com/go-skynet/go-bert.cpp v0.0.0-20230516063724-cea1ed76a7f4/go.mod h1:VY0s5KoAI2jRCvQXKuDeEEe8KG7VaWifSNJSk+E1KtY= github.com/go-skynet/go-gpt2.cpp v0.0.0-20230509180201-d49823284cc6 h1:XshpypO6ekU09CI19vuzke2a1Es1lV5ZaxA7CUehu0E= github.com/go-skynet/go-gpt2.cpp v0.0.0-20230509180201-d49823284cc6/go.mod h1:1Wj/xbkMfwQSOrhNYK178IzqQHstZbRfhx4s8p1M5VM= +github.com/go-skynet/go-gpt2.cpp v0.0.0-20230512145559-7bff56f02245 h1:IcfYY5uH0DdDXEJKJ8bq0WZCd9guPPd3xllaWNy8LOk= +github.com/go-skynet/go-gpt2.cpp v0.0.0-20230512145559-7bff56f02245/go.mod h1:1Wj/xbkMfwQSOrhNYK178IzqQHstZbRfhx4s8p1M5VM= github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c h1:48I7jpLNGiQeBmF0SFVVbREh8vlG0zN13v9LH5ctXis= github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c/go.mod h1:5VZ9XbcINI0XcHhkcX8GPK8TplFGAzu1Hrg4tNiMCtI= github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b h1:qqxrjY8fYDXQahmCMTCACahm1tbiqHLPUHALkFLyBfo= From 44ffaf86adce1a30dc2e3dffa9e4f9b1c5f904c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 11:52:54 +0200 Subject: [PATCH 13/18] fix(deps): update github.com/go-skynet/go-llama.cpp digest to b7bbefb (#243) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index b2940b5d..1cd33ce8 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-skynet/go-bert.cpp v0.0.0-20230516063724-cea1ed76a7f4 github.com/go-skynet/go-gpt2.cpp v0.0.0-20230512145559-7bff56f02245 github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c - github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b + github.com/go-skynet/go-llama.cpp v0.0.0-20230516230554-b7bbefbe0b84 github.com/gofiber/fiber/v2 v2.45.0 github.com/hashicorp/go-multierror v1.1.1 github.com/mudler/go-stable-diffusion v0.0.0-20230516152536-c0748eca3642 diff --git a/go.sum b/go.sum index bbda762c..09af76da 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,8 @@ github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c h1:48I7 github.com/go-skynet/go-gpt4all-j.cpp v0.0.0-20230422090028-1f7bff57f66c/go.mod h1:5VZ9XbcINI0XcHhkcX8GPK8TplFGAzu1Hrg4tNiMCtI= github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b h1:qqxrjY8fYDXQahmCMTCACahm1tbiqHLPUHALkFLyBfo= github.com/go-skynet/go-llama.cpp v0.0.0-20230510072905-70593fccbe4b/go.mod h1:DLfsPD7tYYnpksERH83HSf7qVNW3FIwmz7/zfYO0/6I= +github.com/go-skynet/go-llama.cpp v0.0.0-20230516230554-b7bbefbe0b84 h1:f5iYF75bAr73Tl8AdtFD5Urs/2bsHKPh52K++jLbsfk= +github.com/go-skynet/go-llama.cpp v0.0.0-20230516230554-b7bbefbe0b84/go.mod h1:jxyQ26t1aKC5Gn782w9WWh5n1133PxCOfkuc01xM4RQ= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= From 7e4616646f48bcc87d91479c9b582467cdbc6f5a Mon Sep 17 00:00:00 2001 From: "ci-robbot [bot]" <105103991+ci-robbot@users.noreply.github.com> Date: Wed, 17 May 2023 11:56:32 +0200 Subject: [PATCH 14/18] :arrow_up: Update go-skynet/go-bert.cpp (#274) Signed-off-by: GitHub Co-authored-by: mudler --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9a3debe7..d9cb7978 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ GOGPT2_VERSION?=7bff56f0224502c1c9ed6258d2a17e8084628827 RWKV_REPO?=https://github.com/donomii/go-rwkv.cpp RWKV_VERSION?=07166da10cb2a9e8854395a4f210464dcea76e47 WHISPER_CPP_VERSION?=95b02d76b04d18e4ce37ed8353a1f0797f1717ea -BERT_VERSION?=33118e0da50318101408986b86a331daeb4a6658 +BERT_VERSION?=cea1ed76a7f48ef386a8e369f6c82c48cdf2d551 BLOOMZ_VERSION?=e9366e82abdfe70565644fbfae9651976714efd1 BUILD_TYPE?= CGO_LDFLAGS?= From 3f739575d8632d623cc4bed3d8c597bd0402760e Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Wed, 17 May 2023 21:01:46 +0200 Subject: [PATCH 15/18] Minor fixes (#285) --- .github/workflows/bump_deps.yaml | 5 +- README.md | 8 ++- api/openai.go | 116 +++++++++++++++++-------------- 3 files changed, 70 insertions(+), 59 deletions(-) diff --git a/.github/workflows/bump_deps.yaml b/.github/workflows/bump_deps.yaml index a10d2af1..3c0f4202 100644 --- a/.github/workflows/bump_deps.yaml +++ b/.github/workflows/bump_deps.yaml @@ -9,9 +9,6 @@ jobs: fail-fast: false matrix: include: - - repository: "go-skynet/go-gpt4all-j.cpp" - variable: "GOGPT4ALLJ_VERSION" - branch: "master" - repository: "go-skynet/go-llama.cpp" variable: "GOLLAMA_VERSION" branch: "master" @@ -30,7 +27,7 @@ jobs: - repository: "go-skynet/bloomz.cpp" variable: "BLOOMZ_VERSION" branch: "main" - - repository: "go-skynet/gpt4all" + - repository: "nomic-ai/gpt4all" variable: "GPT4ALL_VERSION" branch: "main" runs-on: ubuntu-latest diff --git a/README.md b/README.md index d9986e6d..c538ab36 100644 --- a/README.md +++ b/README.md @@ -696,6 +696,8 @@ curl http://localhost:8080/v1/models ### Embeddings +OpenAI docs: https://platform.openai.com/docs/api-reference/embeddings +
The embedding endpoint is experimental and enabled only if the model is configured with `embeddings: true` in its `yaml` file, for example: @@ -742,6 +744,8 @@ curl http://localhost:8080/v1/audio/transcriptions -H "Content-Type: multipart/f ### Image generation +OpenAI docs: https://platform.openai.com/docs/api-reference/images/create + LocalAI supports generating images with Stable diffusion, running on CPU. | mode=0 | mode=1 (winograd/sgemm) | @@ -773,6 +777,8 @@ curl http://localhost:8080/v1/images/generations -H "Content-Type: application/j }' ``` +Note: image generator supports images up to 512x512. You can use other tools however to upscale the image, for instance: https://github.com/upscayl/upscayl. + #### Setup Note: In order to use the `images/generation` endpoint, you need to build LocalAI with `GO_TAGS=stablediffusion`. @@ -847,7 +853,7 @@ Yes! If the client uses OpenAI and supports setting a different base URL to send
-Not currently, as ggml doesn't support GPUs yet: https://github.com/ggerganov/llama.cpp/discussions/915. +There is partial GPU support, see build instructions above.
diff --git a/api/openai.go b/api/openai.go index 19284f24..52d65976 100644 --- a/api/openai.go +++ b/api/openai.go @@ -289,12 +289,14 @@ func chatEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, thread mess := []string{} for _, i := range input.Messages { + var content string r := config.Roles[i.Role] - if r == "" { - r = i.Role + if r != "" { + content = fmt.Sprint(r, " ", i.Content) + } else { + content = i.Content } - content := fmt.Sprint(r, " ", i.Content) mess = append(mess, content) } @@ -491,66 +493,72 @@ func imageEndpoint(cm ConfigMerger, debug bool, loader *model.ModelLoader, image var result []Item for _, i := range config.PromptStrings { - prompts := strings.Split(i, "|") - positive_prompt := prompts[0] - negative_prompt := "" - if len(prompts) > 1 { - negative_prompt = prompts[1] + n := input.N + if input.N == 0 { + n = 1 } + for j := 0; j < n; j++ { + prompts := strings.Split(i, "|") + positive_prompt := prompts[0] + negative_prompt := "" + if len(prompts) > 1 { + negative_prompt = prompts[1] + } - mode := 0 - step := 15 + mode := 0 + step := 15 - if input.Mode != 0 { - mode = input.Mode - } + if input.Mode != 0 { + mode = input.Mode + } - if input.Step != 0 { - step = input.Step - } + if input.Step != 0 { + step = input.Step + } - tempDir := "" - if !b64JSON { - tempDir = imageDir - } - // Create a temporary file - outputFile, err := ioutil.TempFile(tempDir, "b64") - if err != nil { - return err - } - outputFile.Close() - output := outputFile.Name() + ".png" - // Rename the temporary file - err = os.Rename(outputFile.Name(), output) - if err != nil { - return err - } - - baseURL := c.BaseURL() - - fn, err := ImageGeneration(height, width, mode, step, input.Seed, positive_prompt, negative_prompt, output, loader, *config) - if err != nil { - return err - } - if err := fn(); err != nil { - return err - } - - item := &Item{} - - if b64JSON { - defer os.RemoveAll(output) - data, err := os.ReadFile(output) + tempDir := "" + if !b64JSON { + tempDir = imageDir + } + // Create a temporary file + outputFile, err := ioutil.TempFile(tempDir, "b64") + if err != nil { + return err + } + outputFile.Close() + output := outputFile.Name() + ".png" + // Rename the temporary file + err = os.Rename(outputFile.Name(), output) if err != nil { return err } - item.B64JSON = base64.StdEncoding.EncodeToString(data) - } else { - base := filepath.Base(output) - item.URL = baseURL + "/generated-images/" + base - } - result = append(result, *item) + baseURL := c.BaseURL() + + fn, err := ImageGeneration(height, width, mode, step, input.Seed, positive_prompt, negative_prompt, output, loader, *config) + if err != nil { + return err + } + if err := fn(); err != nil { + return err + } + + item := &Item{} + + if b64JSON { + defer os.RemoveAll(output) + data, err := os.ReadFile(output) + if err != nil { + return err + } + item.B64JSON = base64.StdEncoding.EncodeToString(data) + } else { + base := filepath.Base(output) + item.URL = baseURL + "/generated-images/" + base + } + + result = append(result, *item) + } } resp := &OpenAIResponse{ From d15fc5371a9366c6a2c4cca34e78c486b2a5d158 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Wed, 17 May 2023 22:33:02 +0200 Subject: [PATCH 16/18] docs: update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c538ab36..1cbb4143 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ See [examples on how to integrate LocalAI](https://github.com/go-skynet/LocalAI/ ## News +- 17-05-2023: __v1.12.0__ released! 🔥🔥 Minor fixes, plus CUDA (https://github.com/go-skynet/LocalAI/pull/258) support for `llama.cpp`-compatible models and image generation (https://github.com/go-skynet/LocalAI/pull/272). - 16-05-2023: 🔥🔥🔥 Experimental support for CUDA (https://github.com/go-skynet/LocalAI/pull/258) in the `llama.cpp` backend and Stable diffusion CPU image generation (https://github.com/go-skynet/LocalAI/pull/272) in `master`. Now LocalAI can generate images too: From b83e8b950d9b2bd72e4a4a6c327a95addd548473 Mon Sep 17 00:00:00 2001 From: "ci-robbot [bot]" <105103991+ci-robbot@users.noreply.github.com> Date: Thu, 18 May 2023 09:52:35 +0200 Subject: [PATCH 17/18] :arrow_up: Update nomic-ai/gpt4all (#252) Signed-off-by: GitHub Co-authored-by: mudler --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d9cb7978..160c8c15 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ BINARY_NAME=local-ai GOLLAMA_VERSION?=7f9ae4246088f0c08ed322acbae21d69cd2eb547 GPT4ALL_REPO?=https://github.com/nomic-ai/gpt4all -GPT4ALL_VERSION?=a07237e54fcdfdb351913587052ac061a2a7bdff +GPT4ALL_VERSION?=bce2b3025b360af73091da0128b1e91f9bc94f9f GOGPT2_VERSION?=7bff56f0224502c1c9ed6258d2a17e8084628827 RWKV_REPO?=https://github.com/donomii/go-rwkv.cpp RWKV_VERSION?=07166da10cb2a9e8854395a4f210464dcea76e47 From 5617e50ebc8d273f659de1656e32d7c8ad65acea Mon Sep 17 00:00:00 2001 From: "ci-robbot [bot]" <105103991+ci-robbot@users.noreply.github.com> Date: Thu, 18 May 2023 09:52:48 +0200 Subject: [PATCH 18/18] :arrow_up: Update go-skynet/go-llama.cpp (#256) Signed-off-by: GitHub Co-authored-by: mudler --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 160c8c15..523f1523 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GOTEST=$(GOCMD) test GOVET=$(GOCMD) vet BINARY_NAME=local-ai -GOLLAMA_VERSION?=7f9ae4246088f0c08ed322acbae21d69cd2eb547 +GOLLAMA_VERSION?=b7bbefbe0b84262e003387a605842bdd0d099300 GPT4ALL_REPO?=https://github.com/nomic-ai/gpt4all GPT4ALL_VERSION?=bce2b3025b360af73091da0128b1e91f9bc94f9f GOGPT2_VERSION?=7bff56f0224502c1c9ed6258d2a17e8084628827