From efd552f83ed2ded820dfaf14a8341fc79bf4ad0c Mon Sep 17 00:00:00 2001 From: Andres Date: Fri, 6 Feb 2026 09:22:10 +0100 Subject: [PATCH] fix(api)!: Stop model prior to deletion (#8422) * Unload model prior to deletion Signed-off-by: Andres Smith * Fix LFM model in gallery Signed-off-by: Andres Smith * Remove mistakenly added files Signed-off-by: Andres Smith --------- Signed-off-by: Andres Smith --- .github/workflows/backend.yml | 1 + .github/workflows/bump_deps.yaml | 1 + .github/workflows/bump_docs.yaml | 1 + .github/workflows/checksum_checker.yaml | 1 + .github/workflows/dependabot_auto.yml | 2 +- .github/workflows/deploy-explorer.yaml | 1 + .github/workflows/gallery-agent.yaml | 1 + .github/workflows/generate_grpc_cache.yaml | 1 + .github/workflows/generate_intel_image.yaml | 1 + .github/workflows/image.yml | 3 +++ .github/workflows/localaibot_automerge.yml | 2 +- .github/workflows/notify-models.yaml | 4 ++-- .github/workflows/notify-releases.yaml | 1 + .github/workflows/stalebot.yml | 1 + .github/workflows/update_swagger.yaml | 1 + backend/go/whisper/Makefile | 2 +- core/services/models.go | 3 +++ gallery/index.yaml | 6 +++--- pkg/system/capabilities.go | 10 +++++++--- 19 files changed, 32 insertions(+), 11 deletions(-) diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index fd1fc6134..ac6766950 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -14,6 +14,7 @@ concurrency: jobs: backend-jobs: + if: github.repository == 'mudler/LocalAI' uses: ./.github/workflows/backend_build.yml with: tag-latest: ${{ matrix.tag-latest }} diff --git a/.github/workflows/bump_deps.yaml b/.github/workflows/bump_deps.yaml index 942bdb989..c1786e16d 100644 --- a/.github/workflows/bump_deps.yaml +++ b/.github/workflows/bump_deps.yaml @@ -5,6 +5,7 @@ on: workflow_dispatch: jobs: bump-backends: + if: github.repository == 'mudler/LocalAI' strategy: fail-fast: false matrix: diff --git a/.github/workflows/bump_docs.yaml b/.github/workflows/bump_docs.yaml index 0437d084c..1fe355580 100644 --- a/.github/workflows/bump_docs.yaml +++ b/.github/workflows/bump_docs.yaml @@ -5,6 +5,7 @@ on: workflow_dispatch: jobs: bump-docs: + if: github.repository == 'mudler/LocalAI' strategy: fail-fast: false matrix: diff --git a/.github/workflows/checksum_checker.yaml b/.github/workflows/checksum_checker.yaml index 78ea95690..e3b1965e9 100644 --- a/.github/workflows/checksum_checker.yaml +++ b/.github/workflows/checksum_checker.yaml @@ -5,6 +5,7 @@ on: workflow_dispatch: jobs: checksum_check: + if: github.repository == 'mudler/LocalAI' runs-on: ubuntu-latest steps: - name: Force Install GIT latest diff --git a/.github/workflows/dependabot_auto.yml b/.github/workflows/dependabot_auto.yml index 873016ee1..a50107b86 100644 --- a/.github/workflows/dependabot_auto.yml +++ b/.github/workflows/dependabot_auto.yml @@ -9,8 +9,8 @@ permissions: jobs: dependabot: + if: github.repository == 'mudler/LocalAI' && github.actor == 'dependabot[bot]' runs-on: ubuntu-latest - if: ${{ github.actor == 'dependabot[bot]' }} steps: - name: Dependabot metadata id: metadata diff --git a/.github/workflows/deploy-explorer.yaml b/.github/workflows/deploy-explorer.yaml index b9e4541fa..5c2a0e354 100644 --- a/.github/workflows/deploy-explorer.yaml +++ b/.github/workflows/deploy-explorer.yaml @@ -12,6 +12,7 @@ concurrency: jobs: build-linux: + if: github.repository == 'mudler/LocalAI' runs-on: ubuntu-latest steps: - name: Clone diff --git a/.github/workflows/gallery-agent.yaml b/.github/workflows/gallery-agent.yaml index a78d1f436..eb3e6374c 100644 --- a/.github/workflows/gallery-agent.yaml +++ b/.github/workflows/gallery-agent.yaml @@ -27,6 +27,7 @@ on: type: string jobs: gallery-agent: + if: github.repository == 'mudler/LocalAI' runs-on: ubuntu-latest steps: - name: Checkout repository diff --git a/.github/workflows/generate_grpc_cache.yaml b/.github/workflows/generate_grpc_cache.yaml index 72a2b3067..f054d8ed3 100644 --- a/.github/workflows/generate_grpc_cache.yaml +++ b/.github/workflows/generate_grpc_cache.yaml @@ -13,6 +13,7 @@ concurrency: jobs: generate_caches: + if: github.repository == 'mudler/LocalAI' strategy: matrix: include: diff --git a/.github/workflows/generate_intel_image.yaml b/.github/workflows/generate_intel_image.yaml index c417ceeb8..45a682a64 100644 --- a/.github/workflows/generate_intel_image.yaml +++ b/.github/workflows/generate_intel_image.yaml @@ -12,6 +12,7 @@ concurrency: jobs: generate_caches: + if: github.repository == 'mudler/LocalAI' strategy: matrix: include: diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml index d84601c3a..a77f74165 100644 --- a/.github/workflows/image.yml +++ b/.github/workflows/image.yml @@ -14,6 +14,7 @@ jobs: hipblas-jobs: + if: github.repository == 'mudler/LocalAI' uses: ./.github/workflows/image_build.yml with: tag-latest: ${{ matrix.tag-latest }} @@ -50,6 +51,7 @@ ubuntu-codename: 'noble' core-image-build: + if: github.repository == 'mudler/LocalAI' uses: ./.github/workflows/image_build.yml with: tag-latest: ${{ matrix.tag-latest }} @@ -136,6 +138,7 @@ ubuntu-codename: 'noble' gh-runner: + if: github.repository == 'mudler/LocalAI' uses: ./.github/workflows/image_build.yml with: tag-latest: ${{ matrix.tag-latest }} diff --git a/.github/workflows/localaibot_automerge.yml b/.github/workflows/localaibot_automerge.yml index a1513802b..e15ca296d 100644 --- a/.github/workflows/localaibot_automerge.yml +++ b/.github/workflows/localaibot_automerge.yml @@ -10,8 +10,8 @@ permissions: actions: write # to dispatch publish workflow jobs: dependabot: + if: github.repository == 'mudler/LocalAI' && github.actor == 'localai-bot' && !contains(github.event.pull_request.title, 'chore(model gallery):') runs-on: ubuntu-latest - if: ${{ github.actor == 'localai-bot' && !contains(github.event.pull_request.title, 'chore(model gallery):') }} steps: - name: Checkout repository uses: actions/checkout@v6 diff --git a/.github/workflows/notify-models.yaml b/.github/workflows/notify-models.yaml index 2928fdaf4..1ab9b5586 100644 --- a/.github/workflows/notify-models.yaml +++ b/.github/workflows/notify-models.yaml @@ -10,7 +10,7 @@ permissions: jobs: notify-discord: - if: ${{ (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'area/ai-model')) }} + if: github.repository == 'mudler/LocalAI' && (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'area/ai-model')) env: MODEL_NAME: gemma-3-12b-it-qat runs-on: ubuntu-latest @@ -90,7 +90,7 @@ jobs: connect-timeout-seconds: 180 limit-access-to-actor: true notify-twitter: - if: ${{ (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'area/ai-model')) }} + if: github.repository == 'mudler/LocalAI' && (github.event.pull_request.merged == true) && (contains(github.event.pull_request.labels.*.name, 'area/ai-model')) env: MODEL_NAME: gemma-3-12b-it-qat runs-on: ubuntu-latest diff --git a/.github/workflows/notify-releases.yaml b/.github/workflows/notify-releases.yaml index b7c6bf847..eab8ce54f 100644 --- a/.github/workflows/notify-releases.yaml +++ b/.github/workflows/notify-releases.yaml @@ -6,6 +6,7 @@ on: jobs: notify-discord: + if: github.repository == 'mudler/LocalAI' runs-on: ubuntu-latest env: RELEASE_BODY: ${{ github.event.release.body }} diff --git a/.github/workflows/stalebot.yml b/.github/workflows/stalebot.yml index 07407fbb0..3e96807d3 100644 --- a/.github/workflows/stalebot.yml +++ b/.github/workflows/stalebot.yml @@ -8,6 +8,7 @@ on: jobs: stale: + if: github.repository == 'mudler/LocalAI' runs-on: ubuntu-latest steps: - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v9 diff --git a/.github/workflows/update_swagger.yaml b/.github/workflows/update_swagger.yaml index b0ca6455a..75e1bbeca 100644 --- a/.github/workflows/update_swagger.yaml +++ b/.github/workflows/update_swagger.yaml @@ -5,6 +5,7 @@ on: workflow_dispatch: jobs: swagger: + if: github.repository == 'mudler/LocalAI' strategy: fail-fast: false runs-on: ubuntu-latest diff --git a/backend/go/whisper/Makefile b/backend/go/whisper/Makefile index 724bbe764..076f9372f 100644 --- a/backend/go/whisper/Makefile +++ b/backend/go/whisper/Makefile @@ -78,7 +78,7 @@ package: whisper build: package clean: purge - rm -rf libgowhisper*.so sources/whisper.cpp whisper + rm -rf libgowhisper*.so package sources/whisper.cpp whisper purge: rm -rf build* diff --git a/core/services/models.go b/core/services/models.go index 1f8967987..383dee9b6 100644 --- a/core/services/models.go +++ b/core/services/models.go @@ -197,6 +197,9 @@ func processModelOperation( switch { case op.Delete: + if err := modelLoader.ShutdownModel(op.GalleryElementName); err != nil { + xlog.Warn("Failed to unload model during deletion", "model", op.GalleryElementName, "error", err) + } return gallery.DeleteModelFromSystem(systemState, op.GalleryElementName) case op.GalleryElement != nil: installedModel, err := gallery.InstallModel( diff --git a/gallery/index.yaml b/gallery/index.yaml index c5079088b..b52d258c6 100644 --- a/gallery/index.yaml +++ b/gallery/index.yaml @@ -1391,7 +1391,7 @@ - filename: mmproj-OpenGVLab_InternVL3_5-2B-f16.gguf sha256: e83ba6e675b747f7801557dc24594f43c17a7850b6129d4972d55e3e9b010359 uri: huggingface://bartowski/OpenGVLab_InternVL3_5-8B-GGUF/mmproj-OpenGVLab_InternVL3_5-2B-f16.gguf -- &lfm2 +- &lfm2vl url: "github:mudler/LocalAI/gallery/lfm.yaml@master" name: "lfm2-vl-450m" license: lfm1.0 @@ -1424,7 +1424,7 @@ - filename: mmproj-LFM2-VL-450M-F16.gguf sha256: 416a085c5c7ba0f8d02bb8326c719a6f8f2210c2641c6bf64194a57c11c76e59 uri: huggingface://LiquidAI/LFM2-VL-450M-GGUF/mmproj-LFM2-VL-450M-F16.gguf -- !!merge <<: *lfm2 +- !!merge <<: *lfm2vl name: "lfm2-vl-1.6b" urls: - https://huggingface.co/LiquidAI/LFM2-VL-1.6B @@ -1440,7 +1440,7 @@ - filename: mmproj-LFM2-VL-1.6B-F16.gguf sha256: b637bfa6060be2bc7503ec23ba48b407843d08c2ca83f52be206ea8563ccbae2 uri: huggingface://LiquidAI/LFM2-VL-1.6B-GGUF/mmproj-LFM2-VL-1.6B-F16.gguf -- !!merge <<: *lfm2 +- &lfm2 name: "lfm2-1.2b" urls: - https://huggingface.co/LiquidAI/LFM2-1.2B diff --git a/pkg/system/capabilities.go b/pkg/system/capabilities.go index 60e05a3e8..c8819ade3 100644 --- a/pkg/system/capabilities.go +++ b/pkg/system/capabilities.go @@ -45,8 +45,9 @@ const ( ) var ( - cuda13DirExists bool - cuda12DirExists bool + cuda13DirExists bool + cuda12DirExists bool + capabilityLogged bool ) func init() { @@ -133,7 +134,10 @@ func (s *SystemState) getSystemCapabilities() string { return defaultCapability } - xlog.Info("Capability automatically detected", "capability", s.GPUVendor, "env", capabilityEnv) + if !capabilityLogged { + xlog.Info("Capability automatically detected", "capability", s.GPUVendor, "env", capabilityEnv) + capabilityLogged = true + } // If vram is less than 4GB, let's default to CPU but warn the user that they can override that via env if s.VRAM <= 4*1024*1024*1024 { xlog.Warn("VRAM is less than 4GB, defaulting to CPU", "env", capabilityEnv)