diff --git a/.github/workflows/generate_grpc_cache.yaml b/.github/workflows/generate_grpc_cache.yaml index b52a137cd96..3d80b967be4 100644 --- a/.github/workflows/generate_grpc_cache.yaml +++ b/.github/workflows/generate_grpc_cache.yaml @@ -84,7 +84,7 @@ jobs: build-args: | GRPC_BASE_IMAGE=${{ matrix.grpc-base-image }} GRPC_MAKEFLAGS=--jobs=4 --output-sync=target - GRPC_VERSION=v1.63.0 + GRPC_VERSION=v1.64.0 context: . file: ./Dockerfile cache-to: type=gha,ignore-error=true diff --git a/.github/workflows/image_build.yml b/.github/workflows/image_build.yml index 4b5ebecdc94..2a4c4aed34a 100644 --- a/.github/workflows/image_build.yml +++ b/.github/workflows/image_build.yml @@ -218,7 +218,7 @@ jobs: BASE_IMAGE=${{ inputs.base-image }} GRPC_BASE_IMAGE=${{ inputs.grpc-base-image || inputs.base-image }} GRPC_MAKEFLAGS=--jobs=4 --output-sync=target - GRPC_VERSION=v1.63.0 + GRPC_VERSION=v1.64.0 MAKEFLAGS=${{ inputs.makeflags }} context: . file: ./Dockerfile diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 8ff64a3f337..bcd4b9da714 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -5,7 +5,7 @@ on: - pull_request env: - GRPC_VERSION: v1.63.0 + GRPC_VERSION: v1.64.0 permissions: contents: write diff --git a/.github/workflows/test-extra.yml b/.github/workflows/test-extra.yml index b06812fd045..0ec6ef9ef73 100644 --- a/.github/workflows/test-extra.yml +++ b/.github/workflows/test-extra.yml @@ -29,7 +29,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get install -y ca-certificates cmake curl patch python3-pip sudo apt-get install -y libopencv-dev - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test transformers run: | @@ -51,7 +51,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get install -y ca-certificates cmake curl patch python3-pip sudo apt-get install -y libopencv-dev - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test sentencetransformers run: | @@ -74,7 +74,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get install -y ca-certificates cmake curl patch python3-pip sudo apt-get install -y libopencv-dev - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test rerankers run: | @@ -96,7 +96,7 @@ jobs: sudo apt-get install -y libopencv-dev # Install UV curl -LsSf https://astral.sh/uv/install.sh | sh - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test diffusers run: | make --jobs=5 --output-sync=target -C backend/python/diffusers @@ -117,7 +117,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get install -y ca-certificates cmake curl patch python3-pip sudo apt-get install -y libopencv-dev - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test parler-tts run: | @@ -139,7 +139,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get install -y ca-certificates cmake curl patch python3-pip sudo apt-get install -y libopencv-dev - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test openvoice run: | @@ -161,7 +161,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get install -y ca-certificates cmake curl patch python3-pip sudo apt-get install -y libopencv-dev - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test transformers-musicgen run: | @@ -185,7 +185,7 @@ jobs: # curl -LsSf https://astral.sh/uv/install.sh | sh # sudo apt-get install -y ca-certificates cmake curl patch python3-pip # sudo apt-get install -y libopencv-dev - # pip install --user grpcio-tools==1.63.0 + # pip install --user grpcio-tools==1.64.0 # - name: Test petals # run: | @@ -249,7 +249,7 @@ jobs: # curl -LsSf https://astral.sh/uv/install.sh | sh # sudo apt-get install -y ca-certificates cmake curl patch python3-pip # sudo apt-get install -y libopencv-dev - # pip install --user grpcio-tools==1.63.0 + # pip install --user grpcio-tools==1.64.0 # - name: Test bark # run: | @@ -274,7 +274,7 @@ jobs: # curl -LsSf https://astral.sh/uv/install.sh | sh # sudo apt-get install -y ca-certificates cmake curl patch python3-pip # sudo apt-get install -y libopencv-dev - # pip install --user grpcio-tools==1.63.0 + # pip install --user grpcio-tools==1.64.0 # - name: Test vllm # run: | # make --jobs=5 --output-sync=target -C backend/python/vllm @@ -294,7 +294,7 @@ jobs: curl -LsSf https://astral.sh/uv/install.sh | sh sudo apt-get install -y ca-certificates cmake curl patch python3-pip sudo apt-get install -y libopencv-dev - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test vall-e-x run: | make --jobs=5 --output-sync=target -C backend/python/vall-e-x @@ -314,7 +314,7 @@ jobs: sudo apt-get install -y ca-certificates cmake curl patch espeak espeak-ng python3-pip # Install UV curl -LsSf https://astral.sh/uv/install.sh | sh - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test coqui run: | make --jobs=5 --output-sync=target -C backend/python/coqui diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4d73f21954e..be704187740 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ on: - '*' env: - GRPC_VERSION: v1.63.0 + GRPC_VERSION: v1.64.0 concurrency: group: ci-tests-${{ github.head_ref || github.ref }}-${{ github.repository }} @@ -213,7 +213,7 @@ jobs: - name: Dependencies run: | brew install protobuf grpc make protoc-gen-go protoc-gen-go-grpc - pip install --user grpcio-tools==1.63.0 + pip install --user grpcio-tools==1.64.0 - name: Test run: | export C_INCLUDE_PATH=/usr/local/include diff --git a/backend/python/autogptq/requirements.txt b/backend/python/autogptq/requirements.txt index 05dac8c8fc6..7a18bfc0de7 100644 --- a/backend/python/autogptq/requirements.txt +++ b/backend/python/autogptq/requirements.txt @@ -1,6 +1,6 @@ accelerate auto-gptq==0.7.1 -grpcio==1.63.0 +grpcio==1.64.0 protobuf torch certifi diff --git a/backend/python/bark/requirements.txt b/backend/python/bark/requirements.txt index 2aec63f7d9b..6680a8b5afe 100644 --- a/backend/python/bark/requirements.txt +++ b/backend/python/bark/requirements.txt @@ -1,6 +1,6 @@ accelerate bark==0.1.5 -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi transformers \ No newline at end of file diff --git a/backend/python/common/template/requirements.txt b/backend/python/common/template/requirements.txt index 8859595c3a4..4a3bd2bc8ec 100644 --- a/backend/python/common/template/requirements.txt +++ b/backend/python/common/template/requirements.txt @@ -1,2 +1,2 @@ -grpcio==1.63.0 +grpcio==1.64.0 protobuf \ No newline at end of file diff --git a/backend/python/coqui/requirements.txt b/backend/python/coqui/requirements.txt index b7c7faf39fa..24621f341ef 100644 --- a/backend/python/coqui/requirements.txt +++ b/backend/python/coqui/requirements.txt @@ -1,6 +1,6 @@ accelerate TTS==0.22.0 -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi transformers \ No newline at end of file diff --git a/backend/python/diffusers/requirements.txt b/backend/python/diffusers/requirements.txt index 84b34302270..1c663adc3d0 100644 --- a/backend/python/diffusers/requirements.txt +++ b/backend/python/diffusers/requirements.txt @@ -1,7 +1,7 @@ accelerate compel diffusers -grpcio==1.63.0 +grpcio==1.64.0 opencv-python pillow protobuf diff --git a/backend/python/exllama/requirements.txt b/backend/python/exllama/requirements.txt index 784e50b0c40..7a1d5464cdd 100644 --- a/backend/python/exllama/requirements.txt +++ b/backend/python/exllama/requirements.txt @@ -1,4 +1,4 @@ -grpcio==1.63.0 +grpcio==1.64.0 protobuf torch transformers diff --git a/backend/python/exllama2/requirements.txt b/backend/python/exllama2/requirements.txt index 25cd1e65769..e9aa977f282 100644 --- a/backend/python/exllama2/requirements.txt +++ b/backend/python/exllama2/requirements.txt @@ -1,5 +1,5 @@ accelerate -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi torch diff --git a/backend/python/mamba/requirements.txt b/backend/python/mamba/requirements.txt index f8225c1cad5..8b08951279b 100644 --- a/backend/python/mamba/requirements.txt +++ b/backend/python/mamba/requirements.txt @@ -1,6 +1,6 @@ causal-conv1d==1.2.0.post2 mamba-ssm==1.2.0.post1 -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi transformers \ No newline at end of file diff --git a/backend/python/openvoice/requirements-intel.txt b/backend/python/openvoice/requirements-intel.txt index 421615e94ad..ba299a572d7 100644 --- a/backend/python/openvoice/requirements-intel.txt +++ b/backend/python/openvoice/requirements-intel.txt @@ -2,7 +2,7 @@ intel-extension-for-pytorch torch optimum[openvino] -grpcio==1.63.0 +grpcio==1.64.0 protobuf librosa==0.9.1 faster-whisper==0.9.0 diff --git a/backend/python/openvoice/requirements.txt b/backend/python/openvoice/requirements.txt index c186bd5a9fe..ac2e8dcd563 100644 --- a/backend/python/openvoice/requirements.txt +++ b/backend/python/openvoice/requirements.txt @@ -1,4 +1,4 @@ -grpcio==1.63.0 +grpcio==1.64.0 protobuf librosa==0.9.1 faster-whisper==0.9.0 diff --git a/backend/python/parler-tts/requirements.txt b/backend/python/parler-tts/requirements.txt index 31085e3d8ab..ba30594fa4d 100644 --- a/backend/python/parler-tts/requirements.txt +++ b/backend/python/parler-tts/requirements.txt @@ -1,5 +1,5 @@ accelerate -grpcio==1.63.0 +grpcio==1.64.0 protobuf torch git+https://github.com/huggingface/parler-tts.git@10016fb0300c0dc31a0fb70e26f3affee7b62f16 diff --git a/backend/python/rerankers/requirements.txt b/backend/python/rerankers/requirements.txt index c4eac2f44fc..db861321f87 100644 --- a/backend/python/rerankers/requirements.txt +++ b/backend/python/rerankers/requirements.txt @@ -1,6 +1,6 @@ accelerate rerankers[transformers] -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi transformers \ No newline at end of file diff --git a/backend/python/sentencetransformers/requirements.txt b/backend/python/sentencetransformers/requirements.txt index b00dc058bee..d3f4e1f3d5f 100644 --- a/backend/python/sentencetransformers/requirements.txt +++ b/backend/python/sentencetransformers/requirements.txt @@ -1,6 +1,6 @@ accelerate sentence-transformers==2.5.1 transformers -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi \ No newline at end of file diff --git a/backend/python/transformers-musicgen/requirements.txt b/backend/python/transformers-musicgen/requirements.txt index 8f6d7be6546..06588c5c3a4 100644 --- a/backend/python/transformers-musicgen/requirements.txt +++ b/backend/python/transformers-musicgen/requirements.txt @@ -1,6 +1,6 @@ accelerate transformers -grpcio==1.63.0 +grpcio==1.64.0 protobuf torch scipy==1.13.0 diff --git a/backend/python/transformers/requirements.txt b/backend/python/transformers/requirements.txt index 57ceb96de97..5f4f4687a08 100644 --- a/backend/python/transformers/requirements.txt +++ b/backend/python/transformers/requirements.txt @@ -1,6 +1,6 @@ accelerate transformers -grpcio==1.63.0 +grpcio==1.64.0 protobuf torch certifi \ No newline at end of file diff --git a/backend/python/vall-e-x/requirements.txt b/backend/python/vall-e-x/requirements.txt index 075c62314e7..a2a720f20f0 100644 --- a/backend/python/vall-e-x/requirements.txt +++ b/backend/python/vall-e-x/requirements.txt @@ -1,4 +1,4 @@ accelerate -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi \ No newline at end of file diff --git a/backend/python/vllm/requirements.txt b/backend/python/vllm/requirements.txt index 3de0b4e2968..0da43c3a7d9 100644 --- a/backend/python/vllm/requirements.txt +++ b/backend/python/vllm/requirements.txt @@ -1,6 +1,6 @@ accelerate vllm -grpcio==1.63.0 +grpcio==1.64.0 protobuf certifi transformers diff --git a/core/config/backend_config.go b/core/config/backend_config.go index 6b9aa54e1d8..99154c9ab7e 100644 --- a/core/config/backend_config.go +++ b/core/config/backend_config.go @@ -2,6 +2,8 @@ package config import ( "os" + "regexp" + "strings" "github.com/go-skynet/LocalAI/core/schema" "github.com/go-skynet/LocalAI/pkg/downloader" @@ -356,3 +358,25 @@ func (cfg *BackendConfig) SetDefaults(opts ...ConfigLoaderOption) { cfg.Debug = &trueV } } + +func (c *BackendConfig) Validate() bool { + // Simple validation to make sure the model can be correctly loaded + for _, n := range []string{c.Backend, c.Model} { + if strings.HasPrefix(n, string(os.PathSeparator)) || + strings.Contains(n, "..") { + return false + } + } + + if c.Name == "" { + return false + } + + if c.Backend != "" { + // a regex that checks that is a string name with no special characters, except '-' and '_' + re := regexp.MustCompile(`^[a-zA-Z0-9-_]+$`) + return re.MatchString(c.Backend) + } + + return true +} diff --git a/core/config/backend_config_loader.go b/core/config/backend_config_loader.go index cf7238cee57..ce02fc9aa81 100644 --- a/core/config/backend_config_loader.go +++ b/core/config/backend_config_loader.go @@ -143,7 +143,9 @@ func (cm *BackendConfigLoader) LoadBackendConfigFile(file string, opts ...Config } for _, cc := range c { - cm.configs[cc.Name] = *cc + if cc.Validate() { + cm.configs[cc.Name] = *cc + } } return nil } @@ -156,7 +158,12 @@ func (cl *BackendConfigLoader) LoadBackendConfig(file string, opts ...ConfigLoad return fmt.Errorf("cannot read config file: %w", err) } - cl.configs[c.Name] = *c + if c.Validate() { + cl.configs[c.Name] = *c + } else { + return fmt.Errorf("config is not valid") + } + return nil } @@ -297,7 +304,7 @@ func (cm *BackendConfigLoader) LoadBackendConfigsFromPath(path string, opts ...C defer cm.Unlock() entries, err := os.ReadDir(path) if err != nil { - return err + return fmt.Errorf("cannot read directory '%s': %w", path, err) } files := make([]fs.FileInfo, 0, len(entries)) for _, entry := range entries { @@ -314,8 +321,14 @@ func (cm *BackendConfigLoader) LoadBackendConfigsFromPath(path string, opts ...C continue } c, err := ReadBackendConfig(filepath.Join(path, file.Name()), opts...) - if err == nil { + if err != nil { + log.Error().Err(err).Msgf("cannot read config file: %s", file.Name()) + continue + } + if c.Validate() { cm.configs[c.Name] = *c + } else { + log.Error().Err(err).Msgf("config is not valid") } } diff --git a/core/config/backend_config_test.go b/core/config/backend_config_test.go new file mode 100644 index 00000000000..4c1437e385f --- /dev/null +++ b/core/config/backend_config_test.go @@ -0,0 +1,65 @@ +package config_test + +import ( + "io" + "net/http" + "os" + + . "github.com/go-skynet/LocalAI/core/config" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Test cases for config related functions", func() { + Context("Test Read configuration functions", func() { + It("Test Validate", func() { + tmp, err := os.CreateTemp("", "config.yaml") + Expect(err).To(BeNil()) + defer os.Remove(tmp.Name()) + _, err = tmp.WriteString( + `backend: "foo-bar" +parameters: + model: "foo-bar"`) + Expect(err).ToNot(HaveOccurred()) + config, err := ReadBackendConfig(tmp.Name()) + Expect(err).To(BeNil()) + Expect(config).ToNot(BeNil()) + Expect(config.Validate()).To(BeFalse()) + }) + It("Test Validate", func() { + tmp, err := os.CreateTemp("", "config.yaml") + Expect(err).To(BeNil()) + defer os.Remove(tmp.Name()) + _, err = tmp.WriteString( + `name: bar-baz +backend: "foo-bar" +parameters: + model: "foo-bar"`) + Expect(err).ToNot(HaveOccurred()) + config, err := ReadBackendConfig(tmp.Name()) + Expect(err).To(BeNil()) + Expect(config).ToNot(BeNil()) + // two configs in config.yaml + Expect(config.Name).To(Equal("bar-baz")) + Expect(config.Validate()).To(BeTrue()) + + // download https://raw.githubusercontent.com/mudler/LocalAI/master/embedded/models/hermes-2-pro-mistral.yaml + httpClient := http.Client{} + resp, err := httpClient.Get("https://raw.githubusercontent.com/mudler/LocalAI/master/embedded/models/hermes-2-pro-mistral.yaml") + Expect(err).To(BeNil()) + defer resp.Body.Close() + tmp, err = os.CreateTemp("", "config.yaml") + Expect(err).To(BeNil()) + defer os.Remove(tmp.Name()) + _, err = io.Copy(tmp, resp.Body) + Expect(err).To(BeNil()) + config, err = ReadBackendConfig(tmp.Name()) + Expect(err).To(BeNil()) + Expect(config).ToNot(BeNil()) + // two configs in config.yaml + Expect(config.Name).To(Equal("hermes-2-pro-mistral")) + Expect(config.Validate()).To(BeTrue()) + }) + }) +}) diff --git a/core/config/config_suite_test.go b/core/config/config_suite_test.go new file mode 100644 index 00000000000..56052cbb766 --- /dev/null +++ b/core/config/config_suite_test.go @@ -0,0 +1,13 @@ +package config_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Config test suite") +} diff --git a/core/config/config_test.go b/core/config/config_test.go index b18e083f84e..eeb5ad89bfa 100644 --- a/core/config/config_test.go +++ b/core/config/config_test.go @@ -28,16 +28,11 @@ var _ = Describe("Test cases for config related functions", func() { It("Test LoadConfigs", func() { cm := NewBackendConfigLoader() - opts := NewApplicationConfig() - err := cm.LoadBackendConfigsFromPath(opts.ModelPath) + err := cm.LoadBackendConfigsFromPath(os.Getenv("MODELS_PATH")) Expect(err).To(BeNil()) Expect(cm.ListBackendConfigs()).ToNot(BeNil()) - // config should includes gpt4all models's api.config - Expect(cm.ListBackendConfigs()).To(ContainElements("gpt4all")) - - // config should includes gpt2 models's api.config - Expect(cm.ListBackendConfigs()).To(ContainElements("gpt4all-2")) + Expect(cm.ListBackendConfigs()).To(ContainElements("code-search-ada-code-001")) // config should includes text-embedding-ada-002 models's api.config Expect(cm.ListBackendConfigs()).To(ContainElements("text-embedding-ada-002")) diff --git a/pkg/model/process.go b/pkg/model/process.go index ff3b12cc6bf..b7180f5d894 100644 --- a/pkg/model/process.go +++ b/pkg/model/process.go @@ -30,8 +30,10 @@ func (ml *ModelLoader) StopAllExcept(s string) error { } func (ml *ModelLoader) deleteProcess(s string) error { - if err := ml.grpcProcesses[s].Stop(); err != nil { - return err + if _, exists := ml.grpcProcesses[s]; exists { + if err := ml.grpcProcesses[s].Stop(); err != nil { + return err + } } delete(ml.grpcProcesses, s) delete(ml.models, s)