An adapters view in the explorer, filtered by the model a held model was made from; GGUF files told apart as adapter or model by their first bytes; held adapter files marked; and a model's card attaches and detaches held adapters of its architecture, refusing models and mismatched architectures. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package gguf
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
// adapterHeader is the start of a LoRA adapter as llama.cpp's converter
|
|
// writes it, followed by padding that stands in for its tensors.
|
|
func adapterHeader(kind string, pad int) []byte {
|
|
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(3))
|
|
str("general.architecture")
|
|
w(uint32(tString))
|
|
str("qwen2")
|
|
str("general.type")
|
|
w(uint32(tString))
|
|
str(kind)
|
|
str("adapter.type")
|
|
w(uint32(tString))
|
|
str("lora")
|
|
b.Write(make([]byte, pad))
|
|
return b.Bytes()
|
|
}
|
|
|
|
func TestAnAdapterIsToldFromAModelByItsFirstBytes(t *testing.T) {
|
|
var asked string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
asked = r.Header.Get("Range")
|
|
w.WriteHeader(http.StatusPartialContent)
|
|
if r.URL.Path == "/adapter.gguf" {
|
|
_, _ = w.Write(adapterHeader("adapter", 1<<20))
|
|
return
|
|
}
|
|
_, _ = w.Write(header("qwen2"))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
h, err := KindFromURL(t.Context(), srv.Client(), srv.URL+"/adapter.gguf")
|
|
if err != nil || !h.IsAdapter() || h.Architecture != "qwen2" {
|
|
t.Errorf("an adapter read as %+v, %v", h, err)
|
|
}
|
|
if asked != "bytes=0-262143" {
|
|
t.Errorf("asked for %q: the probe should read the start only", asked)
|
|
}
|
|
m, err := KindFromURL(t.Context(), srv.Client(), srv.URL+"/model.gguf")
|
|
if err != nil || m.IsAdapter() || m.Architecture != "qwen2" {
|
|
t.Errorf("a model read as %+v, %v", m, err)
|
|
}
|
|
}
|