mirror of
https://github.com/mudler/LocalAI.git
synced 2026-07-30 09:57:57 -04:00
feat(gallery): add nanbeige4.1-3b meta entry with hardware-resolved variants
Adds the first real meta entry to the gallery index. It resolves to the Q8_0 build on hosts with at least 6GiB of VRAM and to the Q4_K_M build everywhere else, installing either payload under the stable name nanbeige4.1-3b. The entry carries a url equal to its final candidate's url. LocalAI releases that predate candidates support parse the index non-strictly and drop the key silently, so without that url they would list the entry and install nothing. A regression spec parses the index the way those releases do and asserts every meta entry stays installable for them. Also teaches core/schema/gallery-model.schema.json about candidates. The schema sets additionalProperties: false at the top level, so an author following CONTRIBUTING.md and adding the yaml-language-server comment would otherwise get a validation error on this entry. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
@@ -368,3 +368,40 @@ var _ = Describe("InstallModelFromGallery with meta entries", func() {
|
|||||||
Expect(record.URLs).To(ConsistOf("https://example.invalid/qwen3"))
|
Expect(record.URLs).To(ConsistOf("https://example.invalid/qwen3"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var _ = Describe("legacy client compatibility", func() {
|
||||||
|
It("exposes a url on every meta entry to clients that ignore candidates", func() {
|
||||||
|
data, err := os.ReadFile(filepath.Join("..", "..", "gallery", "index.yaml"))
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// Parse exactly as an older LocalAI release would: non-strictly, with
|
||||||
|
// no knowledge of the candidates key.
|
||||||
|
var legacy []struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
URL string `yaml:"url"`
|
||||||
|
}
|
||||||
|
Expect(yaml.Unmarshal(data, &legacy)).To(Succeed())
|
||||||
|
|
||||||
|
var current []gallery.GalleryModel
|
||||||
|
Expect(yaml.Unmarshal(data, ¤t)).To(Succeed())
|
||||||
|
|
||||||
|
urlByName := map[string]string{}
|
||||||
|
for _, e := range legacy {
|
||||||
|
urlByName[e.Name] = e.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
metaCount := 0
|
||||||
|
for _, e := range current {
|
||||||
|
if !e.IsMeta() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
metaCount++
|
||||||
|
// Without a url an old client lists the entry and installs an
|
||||||
|
// empty model, because it silently drops candidates.
|
||||||
|
Expect(urlByName[e.Name]).ToNot(BeEmpty(),
|
||||||
|
"meta entry %q is invisible payload-wise to older clients", e.Name)
|
||||||
|
}
|
||||||
|
Expect(metaCount).To(BeNumerically(">", 0),
|
||||||
|
"expected at least one meta entry in the gallery index")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@@ -56,6 +56,42 @@
|
|||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"candidates": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Ordered variant list of a meta entry. The first candidate the host satisfies is installed, under the meta entry's own name. An entry carrying candidates must not also carry files or config_file.",
|
||||||
|
"minItems": 1,
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["model"],
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of a concrete (non-meta) gallery entry"
|
||||||
|
},
|
||||||
|
"capability": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Host capability this candidate requires, matched exactly and case-sensitively (for example metal, nvidia-cuda-12). Absent matches any host."
|
||||||
|
},
|
||||||
|
"min_vram": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Authored VRAM floor, for example 20GiB. Authoritative: inference never overwrites it."
|
||||||
|
},
|
||||||
|
"backend": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Denormalized by the nightly job for display. Never authored by hand."
|
||||||
|
},
|
||||||
|
"quantization": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Denormalized by the nightly job for display. Never authored by hand."
|
||||||
|
},
|
||||||
|
"inferred_min_vram": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Denormalized by the nightly job as a fallback floor. Never authored by hand; min_vram wins."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
},
|
||||||
"prompt_templates": {
|
"prompt_templates": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"description": "Prompt templates written as .tmpl files",
|
"description": "Prompt templates written as .tmpl files",
|
||||||
|
|||||||
@@ -4234,6 +4234,35 @@
|
|||||||
- filename: llama-cpp/models/Qwen_Qwen3-Next-80B-A3B-Thinking-Q4_K_M.gguf
|
- filename: llama-cpp/models/Qwen_Qwen3-Next-80B-A3B-Thinking-Q4_K_M.gguf
|
||||||
sha256: 83481c75cc6c0837ba9afa52b59b4cd3f85f55dd7aa6c60e27230ff329c81367
|
sha256: 83481c75cc6c0837ba9afa52b59b4cd3f85f55dd7aa6c60e27230ff329c81367
|
||||||
uri: https://huggingface.co/bartowski/Qwen_Qwen3-Next-80B-A3B-Thinking-GGUF/resolve/main/Qwen_Qwen3-Next-80B-A3B-Thinking-Q4_K_M.gguf
|
uri: https://huggingface.co/bartowski/Qwen_Qwen3-Next-80B-A3B-Thinking-GGUF/resolve/main/Qwen_Qwen3-Next-80B-A3B-Thinking-Q4_K_M.gguf
|
||||||
|
- name: nanbeige4.1-3b
|
||||||
|
description: |
|
||||||
|
Nanbeige4.1-3B is built upon Nanbeige4-3B-Base and represents an enhanced iteration of our previous reasoning model, Nanbeige4-3B-Thinking-2511, achieved through further post-training optimization with supervised fine-tuning (SFT) and reinforcement learning (RL). As a highly competitive open-source model at a small parameter scale, Nanbeige4.1-3B illustrates that compact models can simultaneously achieve robust reasoning, preference alignment, and effective agentic behaviors.
|
||||||
|
|
||||||
|
Automatically resolves to the best variant for your hardware: the Q8_0 build where there is enough VRAM for it, the Q4_K_M build otherwise.
|
||||||
|
license: apache-2.0
|
||||||
|
icon: https://cdn-avatars.huggingface.co/v1/production/uploads/646f0d118ff94af23bc44aab/GXHCollpMRgvYqUXQ2BQ7.png
|
||||||
|
urls:
|
||||||
|
- https://huggingface.co/Nanbeige/Nanbeige4.1-3B
|
||||||
|
tags:
|
||||||
|
- nanbeige
|
||||||
|
- 3b
|
||||||
|
- llm
|
||||||
|
- gguf
|
||||||
|
- quantized
|
||||||
|
- chat
|
||||||
|
- reasoning
|
||||||
|
- agent
|
||||||
|
- multilingual
|
||||||
|
- instruction-tuned
|
||||||
|
# url is the fallback for LocalAI releases that predate candidates support:
|
||||||
|
# they drop the candidates key silently and would otherwise install nothing.
|
||||||
|
# Lint requires it to equal the final candidate's url exactly, so old and new
|
||||||
|
# clients agree on the least demanding option.
|
||||||
|
url: github:mudler/LocalAI/gallery/nanbeige4.1.yaml@master
|
||||||
|
candidates:
|
||||||
|
- model: nanbeige4.1-3b-q8
|
||||||
|
min_vram: 6GiB
|
||||||
|
- model: nanbeige4.1-3b-q4
|
||||||
- name: nanbeige4.1-3b-q8
|
- name: nanbeige4.1-3b-q8
|
||||||
url: github:mudler/LocalAI/gallery/nanbeige4.1.yaml@master
|
url: github:mudler/LocalAI/gallery/nanbeige4.1.yaml@master
|
||||||
urls:
|
urls:
|
||||||
|
|||||||
Reference in New Issue
Block a user