mirror of
https://github.com/mudler/LocalAI.git
synced 2026-04-25 01:08:13 -04:00
refactor(config): introduce backend hook system and migrate llama-cpp defaults
Adds RegisterBackendHook/runBackendHooks so each backend can register default-filling functions that run during ModelConfig.SetDefaults(). Migrates the existing GGUF guessing logic into hooks_llamacpp.go, registered for both 'llama-cpp' and the empty backend (auto-detect). Removes the old guesser.go shim.
This commit is contained in:
30
core/config/backend_hooks.go
Normal file
30
core/config/backend_hooks.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package config
|
||||
|
||||
// BackendDefaultsHook is called during Prepare() and can modify cfg.
|
||||
// Only fills in values that are not already set by the user.
|
||||
type BackendDefaultsHook func(cfg *ModelConfig, modelPath string)
|
||||
|
||||
var backendHooks = map[string][]BackendDefaultsHook{}
|
||||
|
||||
// RegisterBackendHook registers a hook for a backend name.
|
||||
// Special keys:
|
||||
// - "*" = global catch-all, runs for EVERY backend (before specific hooks)
|
||||
// - "" = runs only when cfg.Backend is empty (auto-detect case)
|
||||
// - "vllm", "llama-cpp" etc. = runs only for that specific backend
|
||||
//
|
||||
// Multiple hooks per key are supported; they run in registration order.
|
||||
func RegisterBackendHook(backend string, hook BackendDefaultsHook) {
|
||||
backendHooks[backend] = append(backendHooks[backend], hook)
|
||||
}
|
||||
|
||||
// runBackendHooks executes hooks in order:
|
||||
// 1. "*" (global) hooks for every backend
|
||||
// 2. Backend-specific hooks for cfg.Backend (includes "" when backend is empty)
|
||||
func runBackendHooks(cfg *ModelConfig, modelPath string) {
|
||||
for _, h := range backendHooks["*"] {
|
||||
h(cfg, modelPath)
|
||||
}
|
||||
for _, h := range backendHooks[cfg.Backend] {
|
||||
h(cfg, modelPath)
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
gguf "github.com/gpustack/gguf-parser-go"
|
||||
"github.com/mudler/xlog"
|
||||
)
|
||||
|
||||
func guessDefaultsFromFile(cfg *ModelConfig, modelPath string, defaultCtx int) {
|
||||
if os.Getenv("LOCALAI_DISABLE_GUESSING") == "true" {
|
||||
xlog.Debug("guessDefaultsFromFile: guessing disabled with LOCALAI_DISABLE_GUESSING")
|
||||
return
|
||||
}
|
||||
|
||||
if modelPath == "" {
|
||||
xlog.Debug("guessDefaultsFromFile: modelPath is empty")
|
||||
return
|
||||
}
|
||||
|
||||
// We try to guess only if we don't have a template defined already
|
||||
guessPath := filepath.Join(modelPath, cfg.ModelFileName())
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
xlog.Error("guessDefaultsFromFile: panic while parsing gguf file")
|
||||
}
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
if cfg.ContextSize == nil {
|
||||
if defaultCtx == 0 {
|
||||
defaultCtx = defaultContextSize
|
||||
}
|
||||
cfg.ContextSize = &defaultCtx
|
||||
}
|
||||
}()
|
||||
|
||||
// try to parse the gguf file
|
||||
f, err := gguf.ParseGGUFFile(guessPath)
|
||||
if err == nil {
|
||||
guessGGUFFromFile(cfg, f, defaultCtx)
|
||||
return
|
||||
}
|
||||
}
|
||||
46
core/config/hooks_llamacpp.go
Normal file
46
core/config/hooks_llamacpp.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
gguf "github.com/gpustack/gguf-parser-go"
|
||||
"github.com/mudler/xlog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register for both explicit llama-cpp and empty backend (auto-detect from GGUF file)
|
||||
RegisterBackendHook("llama-cpp", llamaCppDefaults)
|
||||
RegisterBackendHook("", llamaCppDefaults)
|
||||
}
|
||||
|
||||
func llamaCppDefaults(cfg *ModelConfig, modelPath string) {
|
||||
if os.Getenv("LOCALAI_DISABLE_GUESSING") == "true" {
|
||||
xlog.Debug("llamaCppDefaults: guessing disabled")
|
||||
return
|
||||
}
|
||||
if modelPath == "" {
|
||||
return
|
||||
}
|
||||
|
||||
guessPath := filepath.Join(modelPath, cfg.ModelFileName())
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
xlog.Error("llamaCppDefaults: panic while parsing gguf file")
|
||||
}
|
||||
}()
|
||||
|
||||
// Default context size if not set, regardless of whether GGUF parsing succeeds
|
||||
defer func() {
|
||||
if cfg.ContextSize == nil {
|
||||
ctx := defaultContextSize
|
||||
cfg.ContextSize = &ctx
|
||||
}
|
||||
}()
|
||||
|
||||
f, err := gguf.ParseGGUFFile(guessPath)
|
||||
if err == nil {
|
||||
guessGGUFFromFile(cfg, f, 0)
|
||||
}
|
||||
}
|
||||
@@ -497,7 +497,12 @@ func (cfg *ModelConfig) SetDefaults(opts ...ConfigLoaderOption) {
|
||||
cfg.Debug = &trueV
|
||||
}
|
||||
|
||||
guessDefaultsFromFile(cfg, lo.modelPath, ctx)
|
||||
// If a context size was provided via LoadOptions, apply it before hooks so they
|
||||
// don't override it with their own defaults.
|
||||
if ctx != 0 && cfg.ContextSize == nil {
|
||||
cfg.ContextSize = &ctx
|
||||
}
|
||||
runBackendHooks(cfg, lo.modelPath)
|
||||
cfg.syncKnownUsecasesFromString()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user