ggla.go 2.68 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
39
40

	tensorOffset uint64
Michael Yang's avatar
Michael Yang committed
41
42
}

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

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

54
55
func (llm *ggla) Tensors() *Tensors {
	return &Tensors{
56
57
58
		Items:  llm.tensors,
		Offset: llm.tensorOffset,
	}
Michael Yang's avatar
Michael Yang committed
59
60
}

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

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

74
75
76
77
78
79
80
	offset, err := rs.Seek(0, io.SeekCurrent)
	if err != nil {
		return err
	}

	llm.tensorOffset = uint64(offset)

Michael Yang's avatar
Michael Yang committed
81
82
	for {
		var dims uint32
Michael Yang's avatar
Michael Yang committed
83
		if err := binary.Read(rs, binary.LittleEndian, &dims); err != nil {
84
85
86
			if errors.Is(err, io.EOF) {
				return nil
			}
Michael Yang's avatar
Michael Yang committed
87
88
89
			return err
		}

90
91
92
93
94
95
		defer func() {
			if errors.Is(retErr, io.EOF) {
				retErr = io.ErrUnexpectedEOF
			}
		}()

Michael Yang's avatar
Michael Yang committed
96
		var namesize uint32
Michael Yang's avatar
Michael Yang committed
97
		if err := binary.Read(rs, binary.LittleEndian, &namesize); err != nil {
Michael Yang's avatar
Michael Yang committed
98
99
100
101
			return err
		}

		var t Tensor
Michael Yang's avatar
Michael Yang committed
102
		if err := binary.Read(rs, binary.LittleEndian, &t.Kind); err != nil {
Michael Yang's avatar
Michael Yang committed
103
104
105
106
107
108
			return err
		}

		t.Shape = make([]uint64, dims)
		for i := 0; uint32(i) < dims; i++ {
			var shape32 uint32
Michael Yang's avatar
Michael Yang committed
109
			if err := binary.Read(rs, binary.LittleEndian, &shape32); err != nil {
Michael Yang's avatar
Michael Yang committed
110
111
112
113
114
115
116
117
118
119
120
				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
121
		if err := binary.Read(rs, binary.LittleEndian, &name); err != nil {
Michael Yang's avatar
Michael Yang committed
122
123
124
125
126
			return err
		}

		t.Name = string(name)

Michael Yang's avatar
Michael Yang committed
127
128
		offset, err := rs.Seek(0, io.SeekCurrent)
		if err != nil {
Michael Yang's avatar
Michael Yang committed
129
130
131
			return err
		}

132
		if _, err := rs.Seek((offset+31)&-32-offset, io.SeekCurrent); err != nil {
Michael Yang's avatar
Michael Yang committed
133
134
135
136
137
138
139
140
141
			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
142

Michael Yang's avatar
Michael Yang committed
143
		if _, err := rs.Seek(int64(t.Size()), io.SeekCurrent); err != nil {
Michael Yang's avatar
Michael Yang committed
144
145
146
			return err
		}

Michael Yang's avatar
Michael Yang committed
147
		llm.tensors = append(llm.tensors, &t)
Michael Yang's avatar
Michael Yang committed
148
149
	}
}