add adapter conversion for modelfiles
This commit is contained in:
parent
5d4a331de3
commit
a451611761
@ -63,6 +63,17 @@ type Converter interface {
|
|||||||
writeFile(io.WriteSeeker, llm.KV, []*llm.Tensor) error
|
writeFile(io.WriteSeeker, llm.KV, []*llm.Tensor) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertAdapter(d string, ws io.WriteSeeker) error {
|
||||||
|
c := &adapter{}
|
||||||
|
|
||||||
|
ts, err := parseNPZ(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.writeFile(ws, c.KV(nil), c.Tensors(ts))
|
||||||
|
}
|
||||||
|
|
||||||
func Convert(d string, ws io.WriteSeeker) error {
|
func Convert(d string, ws io.WriteSeeker) error {
|
||||||
f, err := os.Open(filepath.Join(d, "config.json"))
|
f, err := os.Open(filepath.Join(d, "config.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package convert
|
package convert
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ollama/ollama/llm"
|
"github.com/ollama/ollama/llm"
|
||||||
@ -12,6 +13,10 @@ type adapter struct {
|
|||||||
|
|
||||||
var _ Converter = (*adapter)(nil)
|
var _ Converter = (*adapter)(nil)
|
||||||
|
|
||||||
|
func (p *adapter) writeFile(ws io.WriteSeeker, kv llm.KV, ts []*llm.Tensor) error {
|
||||||
|
return llm.WriteGGLA(ws, kv, ts)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *adapter) KV(t *Tokenizer) llm.KV {
|
func (p *adapter) KV(t *Tokenizer) llm.KV {
|
||||||
// todo - need a way to pass these in
|
// todo - need a way to pass these in
|
||||||
kv := llm.KV{
|
kv := llm.KV{
|
||||||
|
@ -18,6 +18,20 @@ type adapterTensor struct {
|
|||||||
*tensorBase
|
*tensorBase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DetectNPZ(fn string) (bool, error) {
|
||||||
|
f, err := npz.Open(fn)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if len(f.Keys()) > 0 && strings.HasSuffix(f.Keys()[0], ".npy") {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseNPZ(fn string) ([]Tensor, error) {
|
func parseNPZ(fn string) ([]Tensor, error) {
|
||||||
var ts []Tensor
|
var ts []Tensor
|
||||||
|
|
||||||
|
@ -129,15 +129,25 @@ func extractFromZipFile(p string, file *os.File, fn func(api.ProgressResponse))
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseFromZipFile(_ context.Context, file *os.File, digest string, fn func(api.ProgressResponse)) (layers []*layerGGML, err error) {
|
func parseFromZipFile(_ context.Context, file *os.File, digest string, fn func(api.ProgressResponse)) (layers []*layerGGML, err error) {
|
||||||
|
layerType := "application/vnd.ollama.image.model"
|
||||||
|
convertAdapter, err := convert.DetectNPZ(file.Name())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
tempDir, err := os.MkdirTemp(filepath.Dir(file.Name()), "")
|
tempDir, err := os.MkdirTemp(filepath.Dir(file.Name()), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(tempDir)
|
defer os.RemoveAll(tempDir)
|
||||||
|
|
||||||
|
if !convertAdapter {
|
||||||
if err := extractFromZipFile(tempDir, file, fn); err != nil {
|
if err := extractFromZipFile(tempDir, file, fn); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
layerType = "application/vnd.ollama.image.adapter"
|
||||||
|
}
|
||||||
|
|
||||||
fn(api.ProgressResponse{Status: "converting model"})
|
fn(api.ProgressResponse{Status: "converting model"})
|
||||||
|
|
||||||
@ -150,15 +160,22 @@ func parseFromZipFile(_ context.Context, file *os.File, digest string, fn func(a
|
|||||||
defer temp.Close()
|
defer temp.Close()
|
||||||
defer os.Remove(temp.Name())
|
defer os.Remove(temp.Name())
|
||||||
|
|
||||||
|
if convertAdapter {
|
||||||
|
slog.Info("convert adapter")
|
||||||
|
if err := convert.ConvertAdapter(file.Name(), temp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if err := convert.Convert(tempDir, temp); err != nil {
|
if err := convert.Convert(tempDir, temp); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := temp.Seek(0, io.SeekStart); err != nil {
|
if _, err := temp.Seek(0, io.SeekStart); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
layer, err := NewLayer(temp, "application/vnd.ollama.image.model")
|
layer, err := NewLayer(temp, layerType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -177,9 +194,13 @@ func parseFromZipFile(_ context.Context, file *os.File, digest string, fn func(a
|
|||||||
layers = append(layers, &layerGGML{layer, ggml})
|
layers = append(layers, &layerGGML{layer, ggml})
|
||||||
|
|
||||||
intermediateBlobs[digest] = layer.Digest
|
intermediateBlobs[digest] = layer.Digest
|
||||||
|
if !convertAdapter {
|
||||||
return detectChatTemplate(layers)
|
return detectChatTemplate(layers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return layers, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseFromFile(ctx context.Context, file *os.File, digest string, fn func(api.ProgressResponse)) (layers []*layerGGML, err error) {
|
func parseFromFile(ctx context.Context, file *os.File, digest string, fn func(api.ProgressResponse)) (layers []*layerGGML, err error) {
|
||||||
sr := io.NewSectionReader(file, 0, 512)
|
sr := io.NewSectionReader(file, 0, 512)
|
||||||
contentType, err := detectContentType(sr)
|
contentType, err := detectContentType(sr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user