ci(gallery): propose variant groupings for review instead of letting them decay#10992
Merged
Conversation
A gallery entry may declare `variants:`, references to other entries that are alternative builds of the same weights, and auto-selection then installs the best build for the host. Those families exist only because humans curated them in two manual sweeps. The gallery agent dedupes on the HuggingFace repo URL and picks one quantization per model, so it never adds a second build of a repo it already has, and consequently never creates a family and never joins one. A model published across two repos lands as two unrelated standalone entries. The grouping decays as the gallery grows and nothing notices. Add a scheduled job, in the same shape as the checksum checker: compute offline, edit the index textually, open a pull request against ci-forks. It proposes and never decides. Grouping is a judgement call that has gone wrong in both directions, so the value is catching drift and surfacing candidates with their evidence. Three grouping signals, taken from the manual sweeps: same name once quantization markers are stripped, the `:` config-suffix convention, and the same primary weight filename once quantization markers are stripped. The third requires the same upstream repository. Excluding auxiliary files is not enough on its own: bert-embeddings, an ultravox audio model and a roleplay finetune all declare a primary file called llama-3.2-1b-instruct-q4_k_m.gguf, and grouping on that is the same error that linked four wan-2.1 entries and Z-Image-Turbo to qwen3-4b. Add gallery/variant-exclusions.yaml, a checked-in rejection ledger. A job that re-proposes declined candidates every night becomes noise and gets ignored. Declining a proposal is one flow-mapping line a reviewer adds inside the proposal pull request itself. Seeded with the six -abliterated pairs whose base is also in the gallery, the mistral-small multimodal pair, the whisper-1 alias, the kokoros language set, and the recurring finetune tokens. qat and apex are deliberately not on it: they are quantization techniques. Proposals refuse to nest, to let two parents claim one target, to target an entry that installs nothing, and to touch a merge anchor, since a variants key added to an anchor is inherited by every merging child. The anchor refusal names every entry that would inherit, which is the worklist a human needs. Run against the pre-sweep gallery, the job rediscovers 12 of the 19 groupings the second manual sweep made, with no false positives. The rest it reports as refusals or ledger declines rather than missing silently. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Gallery entries can declare
variants:, and auto-selection then installs the best build for the host (#10943). Every family in the gallery today exists because a human curated it, across two manual sweeps (#10983 and its predecessor)..github/gallery-agent/adds entries on a schedule. It dedupes on the HuggingFace repo URL and picks exactly one quantization per model, so it never adds a second build of a repo it already has. The consequence is that it never creates a family and never joins one: a model published across two repos lands as two unrelated standalone entries, and the grouping decays as the gallery grows with nothing noticing.What this adds
A weekly job that applies the grouping heuristics from those two sweeps and opens a PR proposing families for review. It never edits the gallery unattended.
That restraint is deliberate. Grouping is a judgement call that went wrong repeatedly by hand: earlier sweeps mis-grouped different parameter sizes, different languages and different finetunes, and had QAT and APEX backwards in both directions. The value here is catching drift and surfacing candidates, not automating the decision.
Modelled on
checksum_checker, which already does compute-offline-and-propose.Validation against human judgement
The useful question is whether the heuristics agree with what people actually decided. Running it against the gallery as it stood before #10983:
12 families proposed. 12 of 12 are groupings #10983 also made. Zero false positives.
Eight of #10983's groupings are not reached, and each is reported rather than silently dropped:
-qatentry already declares its own variants. gallery: group QAT, APEX and cross-backend builds under their base entry #10983 restructured those first; this job only adds. The refusal names the blocker.ultravox-v0_5-llama-3_2-1bas a parent of the llama-3.2 instruct entries and linked inbert-embeddings. Those are primary files, so excluding auxiliary files does not prevent it. Three silent misses are better than three confident wrong families.qwen3-tts-cpp+-0.6b-base-q4is a genuine tension: the parameter-size exclusion forbids it, gallery: group QAT, APEX and cross-backend builds under their base entry #10983 made it anyway. Flagged with the specific rule change that would allow it, rather than resolved silently.Against master as it stands now, with #10983 merged, it proposes nothing and opens no PR.
The rejection ledger
gallery/variant-exclusions.yaml. A proposal job that re-proposes declined candidates forever becomes noise and gets ignored, so declining is recorded and honoured.Flow mappings throughout, so declining a proposal is a one-line edit a reviewer can make inside the proposal PR itself.
Seeded with the decisions already taken: the six
-abliteratedpairs, the mistral-small multimodal pair, thewhisper-1alias, thekokoroslanguage set, and the recurring finetune tokens.qatandapexare deliberately absent, since those were ruled to be quantization techniques. Confirmed load-bearing: removing the ledger takes the pre-#10983 count from 12 to 14, and the two extras are exactly the kokoros set and the mistral pair.Parameter-size and identical-payload exclusions are structural rules rather than ledger rows, since they generalise.
Safety rules
A proposal is refused, with the reason reported, when it would nest variants, claim a target another parent already claims, target an entry that is not independently installable, or touch a YAML merge anchor. The anchor case matters: a
variants:key added to an anchor is inherited by every merging child, which silently mis-groups them. Verified against the real gallery, the refusal names&qwenttscpp_galleryand all nine merging children and states that each needsvariants: [], which is what #10983 hand-edited.On
VariantParentsincore/gallery/collapse_variants.go: its comment says taking the first parent in gallery order keeps the listing deterministic "for a gallery the linter would reject", but the linter does not currently reject a doubly-claimed target. This job will not create one. Adding that lint rule is worth doing separately.Three gallery problems surfaced, none fixed here
whisper-large-q5_0andwhisper-small-q5_1each appear twice ingallery/index.yaml. The job refuses to propose against them, since a variant reference to a duplicated name is ambiguous.bert-embeddingsdeclaresoverrides.parameters.model: llama-3.2-1b-instruct-q4_k_m.gguf, which looks like a stale copy-paste.Verification
77 specs, 0 failures, no network.
core/gallerygreen.make lint0 issues, plusgolangci-lintrun explicitly on the new package since.github/ci/sits outside./.... Build, vet and gofmt clean. Confirmed the index is unmodified on a report-only run.Assisted-by: Claude:claude-opus-4-8 [Claude Code]