ggla.go 2.49 KB
Newer Older
Michael Yang's avatar
Michael Yang committed
1
2
3
4
5
6
7
8
9
package llm

import (
	"encoding/binary"
	"errors"
	"io"
	"slices"
)

10
type containerGGLA struct {
Michael Yang's avatar
Michael Yang committed
11
12
13
	version uint32
}

14
func (c *containerGGLA) Name() string {
Michael Yang's avatar
Michael Yang committed
15
16
17
	return "ggla"
}

18
19
20
21
func (c *containerGGLA) Decode(rs io.ReadSeeker) (model, error) {
	if err := binary.Read(rs, binary.LittleEndian, &c.version); err != nil {
		return nil, err
	}
Michael Yang's avatar
Michael Yang committed
22
23
24
25
26
27
28

	switch c.version {
	case 1:
	default:
		return nil, errors.New("invalid version")
	}

29
	model := newGGLA(c)
Michael Yang's avatar
Michael Yang committed
30
	err := model.decode(rs)
Michael Yang's avatar
Michael Yang committed
31
32
33
	return model, err
}

34
35
type ggla struct {
	*containerGGLA
Michael Yang's avatar
Michael Yang committed
36
37

	kv      KV
Michael Yang's avatar
Michael Yang committed
38
	tensors []*Tensor
Michael Yang's avatar
Michael Yang committed
39
40
}

41
42
43
func newGGLA(container *containerGGLA) *ggla {
	return &ggla{
		containerGGLA: container,
Michael Yang's avatar
Michael Yang committed
44
45
46
47
		kv:            make(KV),
	}
}

Michael Yang's avatar
Michael Yang committed
48
49
50
51
func (llm *ggla) KV() KV {
	return llm.kv
}

Michael Yang's avatar
Michael Yang committed
52
func (llm *ggla) Tensors() Tensors {
Michael Yang's avatar
Michael Yang committed
53
54
55
	return llm.tensors
}

56
func (llm *ggla) decode(rs io.ReadSeeker) (retErr error) {
Michael Yang's avatar
Michael Yang committed
57
	var r uint32
Michael Yang's avatar
Michael Yang committed
58
	if err := binary.Read(rs, binary.LittleEndian, &r); err != nil {
Michael Yang's avatar
Michael Yang committed
59
60
		return err
	}
Michael Yang's avatar
Michael Yang committed
61
	llm.kv["r"] = r
Michael Yang's avatar
Michael Yang committed
62
63

	var alpha uint32
Michael Yang's avatar
Michael Yang committed
64
	if err := binary.Read(rs, binary.LittleEndian, &alpha); err != nil {
Michael Yang's avatar
Michael Yang committed
65
66
		return err
	}
Michael Yang's avatar
Michael Yang committed
67
	llm.kv["alpha"] = alpha
Michael Yang's avatar
Michael Yang committed
68
69
70

	for {
		var dims uint32
Michael Yang's avatar
Michael Yang committed
71
		if err := binary.Read(rs, binary.LittleEndian, &dims); err != nil {
72
73
74
			if errors.Is(err, io.EOF) {
				return nil
			}
Michael Yang's avatar
Michael Yang committed
75
76
77
			return err
		}

78
79
80
81
82
83
		defer func() {
			if errors.Is(retErr, io.EOF) {
				retErr = io.ErrUnexpectedEOF
			}
		}()

Michael Yang's avatar
Michael Yang committed
84
		var namesize uint32
Michael Yang's avatar
Michael Yang committed
85
		if err := binary.Read(rs, binary.LittleEndian, &namesize); err != nil {
Michael Yang's avatar
Michael Yang committed
86
87
88
89
			return err
		}

		var t Tensor
Michael Yang's avatar
Michael Yang committed
90
		if err := binary.Read(rs, binary.LittleEndian, &t.Kind); err != nil {
Michael Yang's avatar
Michael Yang committed
91
92
93
94
95
96
			return err
		}

		t.Shape = make([]uint64, dims)
		for i := 0; uint32(i) < dims; i++ {
			var shape32 uint32
Michael Yang's avatar
Michael Yang committed
97
			if err := binary.Read(rs, binary.LittleEndian, &shape32); err != nil {
Michael Yang's avatar
Michael Yang committed
98
99
100
101
102
103
104
105
106
107
108
				return err
			}

			t.Shape[i] = uint64(shape32)
		}

		// ggla tensor shape is reversed
		// ref: https://github.com/ggerganov/llama.cpp/blob/29ae62d2ae163e2b68aa0ad3bf2ab4636de0c957/convert-lora-to-ggml.py#L44
		slices.Reverse(t.Shape)

		name := make([]byte, namesize)
Michael Yang's avatar
Michael Yang committed
109
		if err := binary.Read(rs, binary.LittleEndian, &name); err != nil {
Michael Yang's avatar
Michael Yang committed
110
111
112
113
114
			return err
		}

		t.Name = string(name)

Michael Yang's avatar
Michael Yang committed
115
116
		offset, err := rs.Seek(0, io.SeekCurrent)
		if err != nil {
Michael Yang's avatar
Michael Yang committed
117
118
119
			return err
		}

120
		if _, err := rs.Seek((offset+31)&-32-offset, io.SeekCurrent); err != nil {
Michael Yang's avatar
Michael Yang committed
121
122
123
124
125
126
127
128
129
			return err
		}

		offset, err = rs.Seek(0, io.SeekCurrent)
		if err != nil {
			return err
		}

		t.Offset = uint64(offset)
Michael Yang's avatar
Michael Yang committed
130

Michael Yang's avatar
Michael Yang committed
131
		if _, err := rs.Seek(int64(t.Size()), io.SeekCurrent); err != nil {
Michael Yang's avatar
Michael Yang committed
132
133
134
			return err
		}

Michael Yang's avatar
Michael Yang committed
135
		llm.tensors = append(llm.tensors, &t)
Michael Yang's avatar
Michael Yang committed
136
137
	}
}