readGgufMetadata function
Reads the string values of keys from the GGUF whose first bytes are
headerPrefix.
Returns as soon as every requested key has been seen, so a modest prefix
(GGUF writers emit general.* keys first) usually suffices; otherwise
the whole key/value section must fit in headerPrefix.
Implementation
GgufMetadataResult readGgufMetadata({
required Uint8List headerPrefix,
required Set<String> keys,
}) {
final reader = GgufReader(headerPrefix);
final values = <String, String>{};
final numericValues = <String, int>{};
try {
if (reader.uint32() != ggufMagic) {
return const GgufMetadataUnsupported('The file is not a GGUF model.');
}
final version = reader.uint32();
if (version < 2 || version > 3) {
return GgufMetadataUnsupported(
'GGUF version $version is not supported (only little-endian v2/v3).',
);
}
reader.uint64(); // tensor count
final kvCount = reader.uint64();
var remaining = keys.toSet();
for (var i = 0; i < kvCount && remaining.isNotEmpty; i++) {
final key = reader.string();
final type = reader.uint32();
if (remaining.remove(key)) {
if (type == ggufTypeString) {
values[key] = reader.string();
} else {
final value = reader.numericValueOrSkip(type);
if (value != null) numericValues[key] = value;
}
} else {
reader.skipValue(type);
}
}
} on GgufTruncated {
return const GgufMetadataNeedsLargerPrefix();
} on FormatException catch (error) {
return GgufMetadataUnsupported(error.message);
}
return GgufMetadata(values, numericValues);
}