mirror of
https://github.com/mudler/LocalAI.git
synced 2026-07-30 09:57:57 -04:00
docs: record that variant selection ranks by engine before size
A gallery entry can now declare variants, and selection ranks the builds a host can run by engine preference before size. Nothing told a contributor adding a backend that engineNamePreferenceRules exists, so a new engine would silently rank below every known one and lose to whatever build happened to be larger on hosts where it should have won. Document the step where a backend is added, warn against the sibling backendBuildTagPreferenceRules table (build tags, not engine names: the wrong table matches nothing, scores every candidate equally and disables the preference without erroring), and index it from AGENTS.md. Fix the authoring and user docs, which still claimed the largest surviving build wins. An author grouping builds under one entry has to be able to predict what a user gets, and size alone no longer decides it. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
@@ -216,6 +216,34 @@ docker-build-backends: ... docker-build-<backend-name>
|
||||
- If the backend is in `backend/python/<backend-name>/` but uses `.` as context in the workflow file, use `.` context
|
||||
- Check similar backends to determine the correct context
|
||||
|
||||
## Engine preference for gallery model variants
|
||||
|
||||
A gallery entry can declare `variants`, alternative builds of the same weights,
|
||||
and LocalAI picks one per host: it drops builds whose backend cannot run here or
|
||||
that do not fit memory, then ranks the survivors by **engine preference first,
|
||||
size second** (`SelectVariant` in `core/gallery/resolve_variant.go`).
|
||||
|
||||
Ask whether your backend should outrank another one on some hardware. If it
|
||||
should, add it to `engineNamePreferenceRules` in `pkg/system/capabilities.go`,
|
||||
best engine first for that capability:
|
||||
|
||||
```go
|
||||
{Nvidia, []string{engineVLLM, engineSGLang, engineLlamaCpp}},
|
||||
+ {Nvidia, []string{engineVLLM, engineSGLang, engineMyEngine, engineLlamaCpp}},
|
||||
```
|
||||
|
||||
That is the ENGINE NAME table, matched against a gallery entry's `backend:`
|
||||
value. The `backendBuildTagPreferenceRules` table next to it is a different
|
||||
vocabulary: build tags (`cuda`, `rocm`, `metal`) matched against installed build
|
||||
directory names for alias resolution. **Putting an engine name in the build tag
|
||||
table, or a build tag in the engine table, matches nothing and does not error**:
|
||||
every candidate scores equal and size alone decides, so the preference silently
|
||||
stops existing. The block comment above both tables spells the contract out.
|
||||
|
||||
Leaving your backend out is a valid choice when no ordering can be justified for
|
||||
it. It then ranks below every known engine and selection falls back to size,
|
||||
which is the behaviour that predates preference.
|
||||
|
||||
## Documenting the backend (README + docs)
|
||||
|
||||
A backend is not "added" until it is discoverable. Update the user-facing docs:
|
||||
@@ -252,6 +280,7 @@ After adding a new backend, verify:
|
||||
- [ ] No Makefile syntax errors (check with linter)
|
||||
- [ ] Follows the same pattern as similar backends (e.g., if it's a transcription backend, follow `faster-whisper` pattern)
|
||||
- [ ] **`Load` validates its input and refuses models it can't serve.** When a model config has no explicit `backend:`, the model loader greedily probes *every* installed backend with the model's name and binds to the first `Load` that succeeds — an accept-anything `Load` will capture arbitrary LLMs (issue #9287). Backends that load a real artefact get this for free (the load fails); backends with no artefact must gate on the name: `opus` accepts only its own name (or none), `local-store` requires the `store.NamespacePrefix` namespace marker sent by `core/backend/stores.go`.
|
||||
- [ ] **Gallery variant ranking considered**: if this backend should be preferred over another on some hardware, it is listed in `engineNamePreferenceRules` (NOT `backendBuildTagPreferenceRules`) in `pkg/system/capabilities.go`. A missing entry silently ranks it last and lets size decide.
|
||||
- [ ] Documented: added to the category list in `docs/content/features/backends.md` (and any new endpoint/realtime capability documented under `docs/content/`)
|
||||
- [ ] If it is an in-house native C/C++/GGML engine, added to the maintained-engines table in the top-level `README.md`
|
||||
|
||||
|
||||
@@ -119,14 +119,23 @@ Rules:
|
||||
- **Order carries no meaning.** Do not try to encode a preference; write the
|
||||
list in whatever order reads best.
|
||||
- **A variant may be smaller than the declaring entry.** Offering a downgrade
|
||||
for small hosts is a normal shape: the declaring entry's own build competes on
|
||||
size like every other candidate, so a large host keeps the large build.
|
||||
for small hosts is a normal shape: the declaring entry's own build competes
|
||||
like every other candidate, so a large host keeps the large build.
|
||||
- **Do not describe hardware.** At install time LocalAI drops variants whose
|
||||
backend cannot run on the host, drops those that do not fit available memory,
|
||||
and installs the largest of what is left, the declaring entry's own build
|
||||
included. That build is never dropped, so selection always terminates on
|
||||
something installable. Sizes are measured live from the weights and cached, so
|
||||
nothing has to be written down.
|
||||
backend cannot run on the host, then drops those that do not fit available
|
||||
memory. The declaring entry's own build is exempt from both filters, so
|
||||
selection always terminates on something installable. Sizes are measured live
|
||||
from the weights and cached, so nothing has to be written down.
|
||||
- **Engine preference outranks size.** Among the builds that survive the
|
||||
filters, the host's preferred engine wins first and only then does the larger
|
||||
footprint win. On NVIDIA a vLLM build beats a larger llama.cpp one; on Apple
|
||||
silicon an MLX build beats a larger GGUF one; on a host with no preference for
|
||||
either engine the larger build wins, since a bigger footprint is a higher
|
||||
quality quantization of the same weights. Predict what a user gets by asking
|
||||
which engine the host prefers before asking which build is biggest. The
|
||||
per-capability order lives in `engineNamePreferenceRules`
|
||||
(`pkg/system/capabilities.go`); see
|
||||
[adding-backends.md](adding-backends.md) for how a backend gets into it.
|
||||
- A variant is nothing but a name; there is no per-variant memory field. When
|
||||
the measured size for a build is wrong, correct it on the referenced entry by
|
||||
setting that entry's own `size:` (e.g. `size: "20GiB"`). The estimator prefers
|
||||
|
||||
@@ -44,4 +44,5 @@ LocalAI follows the Linux kernel project's [guidelines for AI coding assistants]
|
||||
- **Admin endpoints → MCP tool**: every admin endpoint that an admin would manage conversationally (install/list/edit/toggle/upgrade) MUST also be exposed as an MCP tool in `pkg/mcp/localaitools/`. The LocalAI Assistant chat modality and the standalone `local-ai mcp-server` consume that package; drift between REST and MCP is a real risk. Read [.agents/localai-assistant-mcp.md](.agents/localai-assistant-mcp.md) — the `TestToolHTTPRouteMappingComplete` test fails until you wire the new tool and update the route map.
|
||||
- **Build**: Inspect `Makefile` and `.github/workflows/` — ask the user before running long builds
|
||||
- **Backend OS coverage**: a new backend must target every OS it can build for, not just Linux. `.github/backend-matrix.yml` has two matrices — `include:` (Linux) and `includeDarwin:` (macOS / Apple Silicon). Most C/C++/GGML and many Python backends build on Darwin too — wire the `includeDarwin` entry + `backend/index.yaml` `metal:` entries, or say in the PR why an OS is unsupported. See the darwin checklist in [.agents/adding-backends.md](.agents/adding-backends.md).
|
||||
- **Gallery variant ranking**: a gallery entry can declare `variants` (alternative builds of the same weights), and LocalAI ranks the ones a host can run by engine preference first, size second. A new backend that should be preferred on some hardware must be listed in `engineNamePreferenceRules` in `pkg/system/capabilities.go`; the sibling `backendBuildTagPreferenceRules` speaks build tags rather than engine names, and using the wrong table matches nothing without erroring. See [.agents/adding-backends.md](.agents/adding-backends.md).
|
||||
- **UI**: The active UI is the React app in `core/http/react-ui/`. The older Alpine.js/HTML UI in `core/http/static/` is pending deprecation — all new UI work goes in the React UI
|
||||
|
||||
@@ -165,16 +165,21 @@ carries a `variants` list, and installing it normally lets LocalAI choose:
|
||||
- the entry's own build is never dropped. It competes with whatever survived
|
||||
rather than waiting for everything else to fail, so an entry that is itself
|
||||
the largest build that fits keeps its own payload;
|
||||
- the largest remaining build wins, because a bigger footprint means a higher
|
||||
quality build of the same model;
|
||||
- among the remaining builds the engine this machine prefers wins first: a vLLM
|
||||
build on an NVIDIA or AMD host, an MLX build on Apple Silicon, llama.cpp
|
||||
otherwise. The native accelerated runtime is worth more than a bigger
|
||||
download, so preference is settled before size;
|
||||
- the largest build on the preferred engine then wins, because a bigger
|
||||
footprint means a higher quality build of the same model. A machine with no
|
||||
preferred engine picks purely by size;
|
||||
- a build whose size could not be measured ranks below the entry's own build,
|
||||
so an unreadable size never quietly displaces the payload the entry ships;
|
||||
- if nothing else survives, the entry's own build is installed. The entry is
|
||||
always installable, on any machine.
|
||||
|
||||
Because the entry's own build competes on size like every other candidate, the
|
||||
order of the list means nothing and a `variants` list may offer smaller builds,
|
||||
larger ones, or both.
|
||||
Because the entry's own build competes like every other candidate, the order of
|
||||
the list means nothing and a `variants` list may offer smaller builds, larger
|
||||
ones, or both.
|
||||
|
||||
Sizes are measured from the model's weights rather than downloaded, and cached.
|
||||
|
||||
@@ -257,6 +262,9 @@ The same option exists on the CLI:
|
||||
local-ai models install nanbeige4.1-3b-q4 --variant nanbeige4.1-3b-q8
|
||||
```
|
||||
|
||||
The `install_model` MCP tool takes the same `variant` argument, so an assistant
|
||||
managing installs conversationally can pick a build too.
|
||||
|
||||
Entries without a `variants` list are unaffected by any of this and install
|
||||
exactly as they always have.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user