--verbose and README updated.

This commit is contained in:
antirez
2023-12-29 22:50:41 +01:00
parent 54946cbf14
commit 400f60b75b
2 changed files with 35 additions and 8 deletions

View File

@@ -1,22 +1,27 @@
# GGUF tools # GGUF tools
This is a work in progress library to manipulate GGUF files. This is a work in progress library to manipulate GGUF files.
The program 'gguf-tools' use the library to implement both useful and While the library aims to be useful, one of the main goals is to provide
useless stuff, to show the library usage. an accessible code base that as a side effect documents the GGUF
files used by the awesome [llama.cpp](https://github.com/ggerganov/llama.cpp) project.
gguf-tools show file.gguf The program **gguf-tools** use the library to implement both useful and
useless stuff, to show the library usage in the real world. For now
the utility implements the following subcommands:
### gguf-tools show file.gguf
shows detailed info about the GGUF file. This will include all the key-value pairs, including arrays, and detailed tensors informations. Tensor offsets will be relative to the start *of the file* (so they are actually absolute offsets), not the start of the data section like in the GGUF format. shows detailed info about the GGUF file. This will include all the key-value pairs, including arrays, and detailed tensors informations. Tensor offsets will be relative to the start *of the file* (so they are actually absolute offsets), not the start of the data section like in the GGUF format.
gguf-tools compare file1.gguf file2.gguf ### gguf-tools compare file1.gguf file2.gguf
For each matching tensor (same name and parameters count) compute the average weights difference. This is useful to see if a model is a finetune of another model, how much it was finetuned, which layers were frozen while finetuning and so forth. Note that becasue of quantization, even tensors that are functionally equivalent may have some small average difference. For each matching tensor (same name and parameters count) compute the average weights difference. This is useful to see if a model is a finetune of another model, how much it was finetuned, which layers were frozen while finetuning and so forth. Note that becasue of quantization, even tensors that are functionally equivalent may have some small average difference.
gguf-tools inspect-tensor file.gguf tensor.name [count] ### gguf-tools inspect-tensor file.gguf tensor.name [count]
Show all (if count is not specified, otherwise only the first _count_) weights values of the specified tensor. This is useful for low level stuff, like checking if quantization is working as expected, see the introduced error, model fingerprinting and so forth. Show all (if count is not specified, otherwise only the first _count_) weights values of the specified tensor. This is useful for low level stuff, like checking if quantization is working as expected, see the introduced error, model fingerprinting and so forth.
gguf-tools split-mixtral 65230776370407150546470161412165 mixtral.gguf out.gguf ### gguf-tools split-mixtral 65230776370407150546470161412165 mixtral.gguf out.gguf
Extracts a 7B model `out.gguf` from Mixtral 7B MoE using the specified MoE ID for each layer (there are 32 digits in the sequence 652...). Extracts a 7B model `out.gguf` from Mixtral 7B MoE using the specified MoE ID for each layer (there are 32 digits in the sequence 652...).

View File

@@ -158,7 +158,7 @@ void gguf_tools_show(const char *filename) {
gguf_key key; gguf_key key;
while (gguf_get_key(ctx,&key)) { while (gguf_get_key(ctx,&key)) {
printf("%.*s: [%s] ", (int)key.namelen, key.name, gguf_get_value_type_name(key.type)); printf("%.*s: [%s] ", (int)key.namelen, key.name, gguf_get_value_type_name(key.type));
gguf_print_value(ctx,key.type,key.val,0); gguf_print_value(ctx,key.type,key.val,Opt.verbose);
printf("\n"); printf("\n");
} }
@@ -413,7 +413,7 @@ void gguf_tools_compare(const char *file1, const char *file2) {
if (tensor2.namelen == tensor1.namelen && if (tensor2.namelen == tensor1.namelen &&
memcmp(tensor2.name,tensor1.name,tensor1.namelen) == 0) memcmp(tensor2.name,tensor1.name,tensor1.namelen) == 0)
{ {
printf("%.*s: ", (int)tensor1.namelen, tensor1.name); printf("[%.*s]: ", (int)tensor1.namelen, tensor1.name);
fflush(stdout); fflush(stdout);
if (tensor1.num_weights != tensor2.num_weights) { if (tensor1.num_weights != tensor2.num_weights) {
printf("size mismatch\n"); printf("size mismatch\n");
@@ -436,6 +436,8 @@ void gguf_tools_usage(const char *progname) {
" inspect-tensor <filename> <tensor-name> [count] -- show tensor weights.\n" " inspect-tensor <filename> <tensor-name> [count] -- show tensor weights.\n"
" compare <file1> <file2> -- avg weights diff for matching tensor names.\n" " compare <file1> <file2> -- avg weights diff for matching tensor names.\n"
" split-mixtral <ids...> mixtral.gguf out.gguf -- extract expert.\n" " split-mixtral <ids...> mixtral.gguf out.gguf -- extract expert.\n"
"Options:\n"
" --verbose :With 'show', print full arrays (e.g. token lists)\n"
"Example:\n" "Example:\n"
" split-mixtral 65230776370407150546470161412165 mixtral.gguf out.gguf\n" " split-mixtral 65230776370407150546470161412165 mixtral.gguf out.gguf\n"
, progname); , progname);
@@ -445,6 +447,26 @@ void gguf_tools_usage(const char *progname) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
if (argc < 3) gguf_tools_usage(argv[0]); if (argc < 3) gguf_tools_usage(argv[0]);
/* Parse options before getting into subcommands parsing. */
for (int j = 1; j < argc; j++) {
/* Every time we find a an option, we try to parse it
* and set the used argv[] entires to NULL. Later we remove
* the NULL entries. In this way '--options' can be anywhere,
* making the tool simpler to use. */
if (!strcmp(argv[j],"--verbose")) {
argv[j] = NULL;
argc--;
Opt.verbose = 1;
}
}
/* Strip empty elements. */
for (int j = 1; j < argc; j++) {
if (argv[j] == NULL) {
memmove(argv+j, argv+j+1, sizeof(char*) * (argc-j));
}
}
if (!strcmp(argv[1],"show") && argc == 3) { if (!strcmp(argv[1],"show") && argc == 3) {
gguf_tools_show(argv[2]); gguf_tools_show(argv[2]);
} else if (!strcmp(argv[1],"compare") && argc == 4) { } else if (!strcmp(argv[1],"compare") && argc == 4) {