Repository navigation
Expand file tree
/
Copy pathpacked_linear_weights.cpp
More file actions
93 lines (82 loc) · 3.48 KB
/
Copy pathpacked_linear_weights.cpp
File metadata and controls
93 lines (82 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "engine/framework/modules/packed_linear_weights.h"
#include <stdexcept>
#include <string>
#include <utility>
namespace engine::modules {
namespace {
size_t row_bytes(ggml_type type, int64_t columns, const std::string & name) {
const int64_t block_size = ggml_blck_size(type);
if (block_size <= 0 || columns % block_size != 0) {
throw std::runtime_error("Packed linear tensor is not block-aligned: " + name);
}
return ggml_row_size(type, columns);
}
} // namespace
PackedLinearWeightsBuilder::PackedLinearWeightsBuilder(PackedLinearWeightsConfig config) : config_(std::move(config)) {
if (config_.sources.empty()) {
throw std::runtime_error("PackedLinearWeightsBuilder requires at least one source");
}
if (config_.in_features <= 0) {
throw std::runtime_error("PackedLinearWeightsConfig.in_features must be positive");
}
for (const auto & source : config_.sources) {
if (source.out_features <= 0) {
throw std::runtime_error("PackedLinearSource.out_features must be positive");
}
if (config_.use_bias && !source.bias.has_value()) {
throw std::runtime_error("Packed linear source is missing bias");
}
}
}
const PackedLinearWeightsConfig & PackedLinearWeightsBuilder::config() const noexcept {
return config_;
}
LinearWeights PackedLinearWeightsBuilder::build(
core::BackendWeightStore & store,
const assets::TensorSource & source,
assets::TensorStorageType storage_type) const {
const int64_t in_features = config_.in_features;
int64_t out_features = 0;
ggml_type packed_type = GGML_TYPE_COUNT;
std::vector<std::byte> packed_weight;
std::vector<std::byte> packed_bias;
for (const auto & item : config_.sources) {
const auto tensor = source.require_tensor(
item.weight,
storage_type,
{item.out_features, in_features});
if (packed_type == GGML_TYPE_COUNT) {
packed_type = tensor.type;
} else if (packed_type != tensor.type) {
throw std::runtime_error("Packed linear sources resolved to different tensor types");
}
const size_t expected_bytes = row_bytes(tensor.type, in_features, item.weight) * item.out_features;
if (tensor.bytes.size() != expected_bytes) {
throw std::runtime_error("Packed linear tensor byte size mismatch: " + item.weight);
}
packed_weight.insert(packed_weight.end(), tensor.bytes.begin(), tensor.bytes.end());
if (config_.use_bias) {
const auto bias = source.require_tensor(*item.bias, assets::TensorStorageType::F32, {item.out_features});
if (bias.type != GGML_TYPE_F32 || bias.bytes.size() != static_cast<size_t>(item.out_features) * sizeof(float)) {
throw std::runtime_error("Packed linear bias must be F32: " + *item.bias);
}
packed_bias.insert(packed_bias.end(), bias.bytes.begin(), bias.bytes.end());
}
out_features += item.out_features;
}
LinearWeights weights;
weights.weight = store.make_tensor(
core::TensorShape::from_dims({out_features, in_features}),
packed_type,
packed_weight.data(),
packed_weight.size());
if (config_.use_bias) {
weights.bias = store.make_tensor(
core::TensorShape::from_dims({out_features}),
GGML_TYPE_F32,
packed_bias.data(),
packed_bias.size());
}
return weights;
}
} // namespace engine::modules