From 798bb6311c55513215c55900e1da95671b490a61 Mon Sep 17 00:00:00 2001 From: localai-org-maint-bot Date: Mon, 26 Oct 2026 11:07:11 +0100 Subject: [PATCH] fix(gallery): correct HTDemucs checksum (#12919) * fix(watchdog): track models on address-based external backends A backend reached by address has no process, so StartProcess never registered it with the watchdog and LRU and group eviction never saw it loaded. Fixes #12900 Assisted-by: Claude:claude-opus-5-5 * fix(gallery): correct HTDemucs checksum Match the published SHA256 so HTDemucs downloads pass verification. Fixes #12912 Assisted-by: Codex:gpt-6 --------- Co-authored-by: berce <75228263+bercedev@users.noreply.github.com> Co-authored-by: localai-org-maint-bot <306269227+localai-org-maint-bot@users.noreply.github.com> --- gallery/index.yaml | 2 +- pkg/model/initializers.go | 7 +++ .../initializers_external_address_test.go | 45 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 pkg/model/initializers_external_address_test.go diff --git a/gallery/index.yaml b/gallery/index.yaml index e5d16be98..b3d4cc218 100644 --- a/gallery/index.yaml +++ b/gallery/index.yaml @@ -73694,7 +73694,7 @@ - ggml files: - filename: audio-cpp/htdemucs-f16.gguf - sha256: 27763c59d7e65f64bbb326dc0c15beec952291954b70a813b7f4b83ebe6bd0c9 + sha256: f8c54ba35df95aafea7881eac214b58ec18a73cbcb6ff5a90f4b762631a286b6 uri: huggingface://audio-cpp/audio.cpp-gguf/HTDemucs-GGUF/htdemucs-f16.gguf overrides: backend: audio-cpp diff --git a/pkg/model/initializers.go b/pkg/model/initializers.go index 1af257d90..f7fe46980 100644 --- a/pkg/model/initializers.go +++ b/pkg/model/initializers.go @@ -230,6 +230,13 @@ func (ml *ModelLoader) spawnGRPCModel(backend, uri string, o *Options, modelID, ml.wd.RegisterModelSize(modelID, o.modelSizeBytes) } + // StartProcess registers a spawned backend with the watchdog. A backend + // reached by address has no process, so register it here or LRU and group + // eviction never see it loaded. + if ml.wd != nil && client.Process() == nil { + ml.wd.AddAddressModelMap(uri, modelID) + } + return client, nil } diff --git a/pkg/model/initializers_external_address_test.go b/pkg/model/initializers_external_address_test.go new file mode 100644 index 000000000..422369068 --- /dev/null +++ b/pkg/model/initializers_external_address_test.go @@ -0,0 +1,45 @@ +package model + +import ( + "context" + "net" + + pb "github.com/mudler/LocalAI/pkg/grpc/proto" + "github.com/mudler/LocalAI/pkg/system" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "google.golang.org/grpc" +) + +// addressBackend stands in for an external backend that is already running at +// an address, as configured in external_backends.json. +type addressBackend struct{ pb.UnimplementedBackendServer } + +func (addressBackend) Health(context.Context, *pb.HealthMessage) (*pb.Reply, error) { + return &pb.Reply{Message: []byte("OK")}, nil +} + +func (addressBackend) LoadModel(context.Context, *pb.ModelOptions) (*pb.Result, error) { + return &pb.Result{Success: true}, nil +} + +var _ = Describe("address-based external backends", func() { + It("registers the loaded model with the watchdog", func() { + lis, err := net.Listen("tcp", "127.0.0.1:0") + Expect(err).ToNot(HaveOccurred()) + server := grpc.NewServer() + pb.RegisterBackendServer(server, addressBackend{}) + go func() { _ = server.Serve(lis) }() + DeferCleanup(server.Stop) + + loader := NewModelLoader(&system.SystemState{Model: system.Model{ModelsPath: GinkgoT().TempDir()}}) + wd := NewWatchDog(WithProcessManager(loader), WithLRULimit(1)) + loader.SetWatchDog(wd) + options := NewOptions(WithLoadGRPCLoadModelOpts(&pb.ModelOptions{})) + + address := lis.Addr().String() + _, err = loader.spawnGRPCModel("external", address, options, "model-a", "model-a", "") + Expect(err).ToNot(HaveOccurred()) + Expect(wd.GetState().AddressModelMap).To(Equal(map[string]string{address: "model-a"})) + }) +})