Files
Ilker ManapandClaude Opus 5.5 f13b18149a Refuse weights the nodes' llama.cpp cannot load, before fetching them
kev-0.5b declared architecture "ggmlc", which llama.cpp does not know.
It was fetched, catalogued and placed, and failed on every node — while
the answer was in the first kilobytes of the file.

internal/gguf reads a GGUF header (v1-v3) up to general.architecture,
over HTTP with a Range request, and judges it against the architectures
llama.cpp b10991 lists in LLM_ARCH_NAMES (152, copied from the source at
that tag); a vision projector is not a model on its own. An unknown
build is not refused, only not vouched for, and a header that cannot be
fetched does not refuse anything.

Checked in three places: the registry listing (from the architecture
Hugging Face reports with expand[]=gguf, so one request per repository)
shows it and withholds the fetch button; a fetch reads the header and
refuses unless "fetch anyway"; and the model service refuses to add
such a model, which covers the serve form and ctl model add.

Tried on real files: the mirror's qwen2.5-1.5b (qwen2) and bge-m3
(bert), and Qwen2.5-0.5B on Hugging Face through its redirect.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 20:44:36 +02:00

97 lines
3.1 KiB
Go

package web
import (
"bytes"
"encoding/binary"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
"gitea.mynodes.xyz/ilker/llmgw/internal/hf"
"gitea.mynodes.xyz/ilker/llmgw/internal/store"
)
// ggufServer serves a GGUF whose header names an architecture.
func ggufServer(t *testing.T, arch string) string {
t.Helper()
var b bytes.Buffer
w := func(v any) { _ = binary.Write(&b, binary.LittleEndian, v) }
str := func(s string) { w(uint64(len(s))); b.WriteString(s) }
b.WriteString("GGUF")
w(uint32(3))
w(uint64(0))
w(uint64(2))
str("general.architecture")
w(uint32(8))
str(arch)
str("general.name")
w(uint32(8))
str("m")
body := b.Bytes()
srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
http.ServeContent(rw, r, "m.gguf", time.Time{}, bytes.NewReader(body))
}))
t.Cleanup(srv.Close)
return srv.URL + "/m.gguf"
}
func mirrorPageLlama(t *testing.T, d MirrorDeps) *http.ServeMux {
t.Helper()
a := fakeAccounts{user: store.User{ID: "u1", Email: "a@example.com", IsAdmin: true}}
p := NewAccountPages(a, nil, nil, "v0", slog.New(slog.NewTextHandler(io.Discard, nil)))
p.SetLlamaCppVersion("b10991")
mux := http.NewServeMux()
p.RegisterAdminMirror(mux, d)
return mux
}
// The file that started this: kev-0.5b, architecture "ggmlc", downloaded,
// catalogued, and refused by llama.cpp on every node it was placed on.
func TestAFileTheNodesCannotLoadIsNotFetched(t *testing.T) {
m := &fakeMirror{}
mux := mirrorPageLlama(t, MirrorDeps{Mirror: m})
src := ggufServer(t, "ggmlc")
body := mirrorPost(t, mux, "/admin/mirror/fetch", url.Values{"csrf": {"tok"},
"source": {src}, "model": {"kev"}, "version": {"v1"}}).Body.String()
if len(m.all) != 0 {
t.Fatal("a file llama.cpp cannot load was sent to the mirror")
}
if !strings.Contains(body, "ggmlc") || !strings.Contains(body, "cannot load") {
t.Errorf("the refusal should say why; got %s", body)
}
// Asked for regardless, it is fetched.
mirrorPost(t, mux, "/admin/mirror/fetch", url.Values{"csrf": {"tok"},
"source": {src}, "model": {"kev"}, "version": {"v1"}, "force": {"1"}})
if len(m.all) != 1 {
t.Error("fetch anyway did not fetch")
}
// And one it can load goes straight through.
m.all = nil
mirrorPost(t, mux, "/admin/mirror/fetch", url.Values{"csrf": {"tok"},
"source": {ggufServer(t, "qwen2")}, "model": {"q"}, "version": {"v1"}})
if len(m.all) != 1 {
t.Error("a qwen2 GGUF was refused")
}
}
func TestTheRegistryListingSaysWhatCannotBeServed(t *testing.T) {
reg := &fakeRegistry{repo: hf.Repo{ID: "someone/kev-gguf", Revision: "abc12345", Architecture: "ggmlc",
Files: []hf.File{{Path: "kev-q4_k_m.gguf", Bytes: 500 << 20}}}}
body := mirrorGet(t, mirrorPageLlama(t, MirrorDeps{Mirror: &fakeMirror{}, Registry: reg}),
"/admin/mirror?q=kev&repo=someone/kev-gguf").Body.String()
if !strings.Contains(body, "cannot be served") {
t.Error("the listing does not say the file cannot be served")
}
if strings.Contains(body, `value="`+"https://huggingface.co") && strings.Contains(body, ">Fetch</button>") {
t.Error("the listing still offers to fetch it")
}
}