mirror of
https://github.com/antirez/gguf-tools.git
synced 2025-09-17 19:08:07 +08:00
Compare subcommand.
This commit is contained in:
@@ -8,6 +8,14 @@ useless stuff, to show the library usage.
|
||||
|
||||
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
|
||||
|
||||
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]
|
||||
|
||||
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
|
||||
|
||||
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...).
|
||||
|
58
gguf-tools.c
58
gguf-tools.c
@@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gguflib.h"
|
||||
#include "sds.h"
|
||||
@@ -372,6 +373,60 @@ void gguf_tools_inspect_weights(const char *filename, const char *tname, uint64_
|
||||
return;
|
||||
}
|
||||
|
||||
/* ========================== 'compare' subcommand ========================== */
|
||||
|
||||
/* Given two tensors of the same length, return the average difference
|
||||
* of their weights. */
|
||||
double tensors_avg_diff(gguf_tensor *t1, gguf_tensor *t2) {
|
||||
float *weights1 = gguf_tensor_to_float(t1);
|
||||
float *weights2 = gguf_tensor_to_float(t2);
|
||||
if (weights1 == NULL || weights2 == NULL) {
|
||||
perror("Error while decoding tensor weights");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
double tot_diff = 0;
|
||||
for (uint64_t j = 0; j < t1->num_weights; j++)
|
||||
tot_diff += fabs(weights1[j]-weights2[j]);
|
||||
free(weights1);
|
||||
free(weights2);
|
||||
return tot_diff/t1->num_weights;
|
||||
}
|
||||
|
||||
void gguf_tools_compare(const char *file1, const char *file2) {
|
||||
gguf_ctx *ctx1 = gguf_init(file1);
|
||||
gguf_ctx *ctx2 = gguf_init(file2);
|
||||
if (ctx1 == NULL || ctx2 == NULL) {
|
||||
perror("Opening GGUF files");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Skip all the key-value pairs. */
|
||||
gguf_skip_key_values_section(ctx1);
|
||||
|
||||
/* For each tensor of the first net... */
|
||||
gguf_tensor tensor1, tensor2;
|
||||
while (gguf_get_tensor(ctx1,&tensor1)) {
|
||||
gguf_skip_key_values_section(ctx2);
|
||||
while (gguf_get_tensor(ctx2,&tensor2)) {
|
||||
/* Search for a tensor with the same name. */
|
||||
if (tensor2.namelen == tensor1.namelen &&
|
||||
memcmp(tensor2.name,tensor1.name,tensor1.namelen) == 0)
|
||||
{
|
||||
printf("%.*s: ", (int)tensor1.namelen, tensor1.name);
|
||||
fflush(stdout);
|
||||
if (tensor1.num_weights != tensor2.num_weights) {
|
||||
printf("size mismatch\n");
|
||||
} else {
|
||||
printf("avg weights difference: %f\n",
|
||||
tensors_avg_diff(&tensor1, &tensor2));
|
||||
}
|
||||
}
|
||||
}
|
||||
gguf_rewind(ctx2);
|
||||
}
|
||||
}
|
||||
|
||||
/* ======================= Main and CLI options parsing ===================== */
|
||||
|
||||
void gguf_tools_usage(const char *progname) {
|
||||
@@ -379,6 +434,7 @@ void gguf_tools_usage(const char *progname) {
|
||||
"Subcommands:\n"
|
||||
" show <filename> -- show GGUF model keys and tensors.\n"
|
||||
" inspect-tensor <filename> <tensor-name> [count] -- show tensor weights.\n"
|
||||
" compare <file1> <file2> -- avg weights diff for matching tensor names.\n"
|
||||
" split-mixtral <ids...> mixtral.gguf out.gguf -- extract expert.\n"
|
||||
"Example:\n"
|
||||
" split-mixtral 65230776370407150546470161412165 mixtral.gguf out.gguf\n"
|
||||
@@ -391,6 +447,8 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (!strcmp(argv[1],"show") && argc == 3) {
|
||||
gguf_tools_show(argv[2]);
|
||||
} else if (!strcmp(argv[1],"compare") && argc == 4) {
|
||||
gguf_tools_compare(argv[2],argv[3]);
|
||||
} else if (!strcmp(argv[1],"inspect-tensor") && (argc == 4 || argc == 5)) {
|
||||
gguf_tools_inspect_weights(argv[2],argv[3],
|
||||
argc == 5 ? atoi(argv[4]) : 0);
|
||||
|
Reference in New Issue
Block a user