Skip to content

Commit d03ff6d

Browse files
committed
gguf: add CLI
1 parent c22681b commit d03ff6d

File tree

3 files changed

+143
-1
lines changed

3 files changed

+143
-1
lines changed

packages/gguf/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,42 @@ In case you want to use your own GGUF metadata structure, you can disable strict
9696
const { metadata, tensorInfos }: GGUFParseOutput<{ strict: false }> = await gguf(URL_LLAMA);
9797
```
9898

99+
## Command line interface
100+
101+
This package provides a CLI equivalent to [`gguf_dump.py`](https://github.com/ggml-org/llama.cpp/blob/7a2c913e66353362d7f28d612fd3c9d51a831eda/gguf-py/gguf/scripts/gguf_dump.py) script. You can dump GGUF metadata and list of tensors using this command:
102+
103+
```bash
104+
npx @huggingface/gguf my_model.gguf
105+
```
106+
107+
Example for the output:
108+
109+
```
110+
* Dumping 36 key/value pair(s)
111+
Idx | Count | Value
112+
----|--------|----------------------------------------------------------------------------------
113+
1 | 1 | version = 3
114+
2 | 1 | tensor_count = 292
115+
3 | 1 | kv_count = 33
116+
4 | 1 | general.architecture = "llama"
117+
5 | 1 | general.type = "model"
118+
6 | 1 | general.name = "Meta Llama 3.1 8B Instruct"
119+
7 | 1 | general.finetune = "Instruct"
120+
8 | 1 | general.basename = "Meta-Llama-3.1"
121+
122+
[truncated]
123+
124+
* Dumping 292 tensor(s)
125+
Idx | Num Elements | Shape | Data Type | Name
126+
----|--------------|--------------------------------|-----------|--------------------------
127+
1 | 64 | 64, 1, 1, 1 | F32 | rope_freqs.weight
128+
2 | 525336576 | 4096, 128256, 1, 1 | Q4_K | token_embd.weight
129+
3 | 4096 | 4096, 1, 1, 1 | F32 | blk.0.attn_norm.weight
130+
4 | 58720256 | 14336, 4096, 1, 1 | Q6_K | blk.0.ffn_down.weight
131+
132+
[truncated]
133+
```
134+
99135
## Hugging Face Hub
100136

101137
The Hub supports all file formats and has built-in features for GGUF format.

packages/gguf/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
"main": "./dist/index.js",
1111
"module": "./dist/index.mjs",
1212
"types": "./dist/index.d.ts",
13+
"bin": {
14+
"gguf-dump": "./dist/cli.js"
15+
},
1316
"exports": {
1417
".": {
1518
"types": "./dist/index.d.ts",
@@ -18,6 +21,7 @@
1821
}
1922
},
2023
"browser": {
24+
"./src/cli.ts": false,
2125
"./src/utils/FileBlob.ts": false,
2226
"./dist/index.js": "./dist/browser/index.js",
2327
"./dist/index.mjs": "./dist/browser/index.mjs"
@@ -32,7 +36,7 @@
3236
"format": "prettier --write .",
3337
"format:check": "prettier --check .",
3438
"prepublishOnly": "pnpm run build",
35-
"build": "tsup src/index.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration",
39+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration",
3640
"build:llm": "tsx scripts/generate-llm.ts && pnpm run format",
3741
"test": "vitest run",
3842
"check": "tsc"

packages/gguf/src/cli.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env node
2+
3+
import { GGMLQuantizationType, gguf } from ".";
4+
5+
interface PrintColumnHeader {
6+
name: string;
7+
maxWidth?: number;
8+
alignRight?: boolean;
9+
}
10+
11+
const mapDtypeToName = Object.fromEntries(Object.entries(GGMLQuantizationType).map(([name, value]) => [value, name]));
12+
13+
async function main() {
14+
const ggufPath = process.argv[2];
15+
const { metadata, tensorInfos } = await gguf(ggufPath, {
16+
allowLocalFile: true,
17+
});
18+
19+
// TODO: print info about endianess
20+
console.log(`* Dumping ${Object.keys(metadata).length} key/value pair(s)`);
21+
printTable(
22+
[
23+
{ name: "Idx", alignRight: true },
24+
// { name: 'Type' }, // TODO: support this
25+
{ name: "Count", alignRight: true },
26+
{ name: "Value" },
27+
],
28+
Object.entries(metadata).map(([key, value], i) => {
29+
const MAX_LEN = 50;
30+
let strVal = "";
31+
let count = 1;
32+
if (Array.isArray(value)) {
33+
strVal = JSON.stringify(value);
34+
count = value.length;
35+
} else if (value instanceof String || typeof value === "string") {
36+
strVal = JSON.stringify(value);
37+
} else {
38+
strVal = value.toString();
39+
}
40+
strVal = strVal.length > MAX_LEN ? strVal.slice(0, MAX_LEN) + "..." : strVal;
41+
return [(i + 1).toString(), count.toString(), `${key} = ${strVal}`];
42+
})
43+
);
44+
45+
console.log();
46+
console.log(`* Dumping ${tensorInfos.length} tensor(s)`);
47+
printTable(
48+
[
49+
{ name: "Idx", alignRight: true },
50+
{ name: "Num Elements", alignRight: true },
51+
{ name: "Shape" },
52+
{ name: "Data Type" },
53+
{ name: "Name" },
54+
],
55+
tensorInfos.map((tensorInfo, i) => {
56+
const shape = [1n, 1n, 1n, 1n];
57+
tensorInfo.shape.forEach((dim, i) => {
58+
shape[i] = dim;
59+
});
60+
return [
61+
(i + 1).toString(),
62+
shape.reduce((acc, n) => acc * n, 1n).toString(),
63+
shape.map((n) => n.toString().padStart(6)).join(", "),
64+
mapDtypeToName[tensorInfo.dtype],
65+
tensorInfo.name,
66+
];
67+
})
68+
);
69+
}
70+
71+
function printTable(header: PrintColumnHeader[], rows: string[][], leftPad = 2) {
72+
const leftPadStr = " ".repeat(leftPad);
73+
74+
// Calculate column widths
75+
const columnWidths = header.map((h, i) => {
76+
const maxContentWidth = Math.max(h.name.length, ...rows.map((row) => (row[i] || "").length));
77+
return h.maxWidth ? Math.min(maxContentWidth, h.maxWidth) : maxContentWidth;
78+
});
79+
80+
// Print header
81+
const headerLine = header
82+
.map((h, i) => {
83+
return h.name.padEnd(columnWidths[i]);
84+
})
85+
.join(" | ");
86+
console.log(leftPadStr + headerLine);
87+
88+
// Print separator
89+
console.log(leftPadStr + columnWidths.map((w) => "-".repeat(w)).join("-|-"));
90+
91+
// Print rows
92+
for (const row of rows) {
93+
const line = header
94+
.map((h, i) => {
95+
return h.alignRight ? (row[i] || "").padStart(columnWidths[i]) : (row[i] || "").padEnd(columnWidths[i]);
96+
})
97+
.join(" | ");
98+
console.log(leftPadStr + line);
99+
}
100+
}
101+
102+
main();

0 commit comments

Comments
 (0)