convert_test.go 2.65 KB
Newer Older
Michael Yang's avatar
Michael Yang committed
1
2
3
package convert

import (
4
	"crypto/sha256"
Michael Yang's avatar
lint  
Michael Yang committed
5
	"encoding/hex"
6
7
8
9
	"encoding/json"
	"flag"
	"fmt"
	"io"
10
	"io/fs"
11
12
	"log/slog"
	"math"
Michael Yang's avatar
Michael Yang committed
13
14
	"os"
	"path/filepath"
15
	"slices"
Michael Yang's avatar
Michael Yang committed
16
17
	"testing"

18
	"golang.org/x/exp/maps"
Michael Yang's avatar
lint  
Michael Yang committed
19
20

	"github.com/ollama/ollama/llm"
Michael Yang's avatar
Michael Yang committed
21
22
)

23
func convertFull(t *testing.T, fsys fs.FS) (*os.File, llm.KV, llm.Tensors) {
Michael Yang's avatar
Michael Yang committed
24
25
26
27
28
29
30
31
	t.Helper()

	f, err := os.CreateTemp(t.TempDir(), "f16")
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

32
	if err := Convert(fsys, f); err != nil {
Michael Yang's avatar
Michael Yang committed
33
34
35
36
37
38
39
		t.Fatal(err)
	}

	r, err := os.Open(f.Name())
	if err != nil {
		t.Fatal(err)
	}
40
	t.Cleanup(func() { r.Close() })
Michael Yang's avatar
Michael Yang committed
41

42
	m, _, err := llm.DecodeGGML(r, math.MaxInt)
Michael Yang's avatar
Michael Yang committed
43
44
45
46
	if err != nil {
		t.Fatal(err)
	}

47
48
49
50
51
52
53
54
55
56
57
58
59
	if _, err := r.Seek(0, io.SeekStart); err != nil {
		t.Fatal(err)
	}

	return r, m.KV(), m.Tensors()
}

func TestMain(m *testing.M) {
	var level slog.Level
	flag.TextVar(&level, "level", slog.LevelInfo, "log level")
	flag.Parse()
	slog.SetLogLoggerLevel(level)
	os.Exit(m.Run())
Michael Yang's avatar
Michael Yang committed
60
61
62
}

func TestConvertFull(t *testing.T) {
63
64
65
66
67
	cases := []string{
		"Meta-Llama-3-8B-Instruct",
		"Mistral-7B-Instruct-v0.2",
		"Mixtral-8x7B-Instruct-v0.1",
		"gemma-2b-it",
68
69
		// microsoft/Phi-3-mini-128-instruct@d548c233192db00165d842bf8edff054bb3212f8
		"Phi-3-mini-128k-instruct",
Michael Yang's avatar
bert  
Michael Yang committed
70
		"all-MiniLM-L6-v2",
Michael Yang's avatar
Michael Yang committed
71
		"gemma-2-9b-it",
Michael Yang's avatar
Michael Yang committed
72
73
	}

74
75
76
77
78
79
80
81
82
	for i := range cases {
		tt := cases[i]
		t.Run(tt, func(t *testing.T) {
			t.Parallel()

			p := filepath.Join("testdata", tt)
			if testing.Short() {
				t.Skip("skipping in short mode")
			} else if _, err := os.Stat(p); err != nil {
Michael Yang's avatar
Michael Yang committed
83
84
85
				t.Skipf("%s not found", p)
			}

86
			f, kv, tensors := convertFull(t, os.DirFS(p))
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
			actual := make(map[string]string)
			for k, v := range kv {
				if s, ok := v.(json.Marshaler); !ok {
					actual[k] = fmt.Sprintf("%v", v)
				} else {
					bts, err := json.Marshal(s)
					if err != nil {
						t.Fatal(err)
					}

					actual[k] = fmt.Sprintf("%x", sha256.Sum256(bts))
				}
			}

			for _, tensor := range tensors.Items {
				sha256sum := sha256.New()
				sr := io.NewSectionReader(f, int64(tensors.Offset+tensor.Offset), int64(tensor.Size()))
				if _, err := io.Copy(sha256sum, sr); err != nil {
					t.Fatal(err)
				}
Michael Yang's avatar
Michael Yang committed
107

Michael Yang's avatar
lint  
Michael Yang committed
108
				actual[tensor.Name] = hex.EncodeToString(sha256sum.Sum(nil))
Michael Yang's avatar
Michael Yang committed
109
110
			}

111
112
113
			expectFile, err := os.Open(filepath.Join("testdata", fmt.Sprintf("%s.json", tt)))
			if err != nil {
				t.Fatal(err)
Michael Yang's avatar
Michael Yang committed
114
115
			}

116
117
118
			var expect map[string]string
			if err := json.NewDecoder(expectFile).Decode(&expect); err != nil {
				t.Fatal(err)
Michael Yang's avatar
Michael Yang committed
119
120
			}

121
122
123
124
125
126
127
128
			keys := maps.Keys(expect)
			slices.Sort(keys)
			for _, k := range keys {
				if v, ok := actual[k]; !ok {
					t.Errorf("missing %s", k)
				} else if v != expect[k] {
					t.Errorf("unexpected %s: want %s, got %s", k, expect[k], v)
				}
Michael Yang's avatar
Michael Yang committed
129
130
131
132
			}
		})
	}
}