|  | 
|  | 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