First upload version 0.0.1

This commit is contained in:
Neyra
2026-02-05 15:27:49 +08:00
commit 8e9b7201ed
4182 changed files with 593136 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
import { GgufReadOffset } from "../utils/GgufReadOffset.js";
import { GgufValueType, GgufVersionParserOptions, GgufVersionParserResult, MetadataKeyValueRecord, MetadataValue } from "../types/GgufFileInfoTypes.js";
import { Promisable } from "../../utils/transformPromisable.js";
export declare class GgufV2Parser {
private readonly _fileReader;
private readonly _shouldReadTensorInfo;
private readonly _ignoreKeys;
private readonly _readOffset;
private readonly _logWarnings;
constructor({ fileReader, readTensorInfo, ignoreKeys, readOffset, logWarnings }: GgufVersionParserOptions);
parse(): Promise<GgufVersionParserResult>;
protected _readGgufValue(type: GgufValueType, offset: number | GgufReadOffset): Promisable<MetadataValue>;
protected _readStringValue(offset: number | GgufReadOffset): Promisable<string>;
protected _readRawHeader(readOffset: GgufReadOffset): Promise<{
tensorCount: number | bigint;
metadata: MetadataKeyValueRecord;
headerSize: number;
}>;
private _readTensorInfo;
}

View File

@@ -0,0 +1,184 @@
import { GgufFileReader } from "../fileReaders/GgufFileReader.js";
import { GgufReadOffset } from "../utils/GgufReadOffset.js";
import { UnsupportedGgufValueTypeError } from "../errors/UnsupportedGgufValueTypeError.js";
import { GgufValueType } from "../types/GgufFileInfoTypes.js";
import { convertMetadataKeyValueRecordToNestedObject } from "../utils/convertMetadataKeyValueRecordToNestedObject.js";
import { promisableLoop, transformPromisable, transformPromisablesInOrder } from "../../utils/transformPromisable.js";
import { noDirectSubNestingGGufMetadataKeys } from "../consts.js";
const ggufDefaultAlignment = 32;
export class GgufV2Parser {
_fileReader;
_shouldReadTensorInfo;
_ignoreKeys;
_readOffset;
_logWarnings;
constructor({ fileReader, readTensorInfo = true, ignoreKeys = [], readOffset, logWarnings }) {
this._fileReader = fileReader;
this._shouldReadTensorInfo = readTensorInfo;
this._ignoreKeys = ignoreKeys;
this._readOffset = readOffset;
this._logWarnings = logWarnings;
}
async parse() {
const readOffset = this._readOffset;
const initialOffset = readOffset.offset;
const headerReadResultPromisable = this._readRawHeader(readOffset);
const headerReadResult = headerReadResultPromisable instanceof Promise
? await headerReadResultPromisable
: headerReadResultPromisable;
const alignmentHeader = headerReadResult.metadata["general.alignment"];
const ggufAlignment = (alignmentHeader != null &&
(typeof alignmentHeader === "number" || typeof alignmentHeader === "bigint") &&
Number.isFinite(Number(alignmentHeader)))
? Number(alignmentHeader)
: ggufDefaultAlignment;
const tensorReadResultPromisable = this._shouldReadTensorInfo
? await this._readTensorInfo(headerReadResult.tensorCount, readOffset, ggufAlignment)
: null;
const tensorReadResult = tensorReadResultPromisable instanceof Promise
? await tensorReadResultPromisable
: tensorReadResultPromisable;
const metadata = convertMetadataKeyValueRecordToNestedObject(headerReadResult.metadata, {
logOverrideWarnings: this._logWarnings,
ignoreKeys: this._ignoreKeys,
noDirectSubNestingKeys: noDirectSubNestingGGufMetadataKeys
});
return {
tensorCount: headerReadResult.tensorCount,
metadata: metadata,
tensorInfo: tensorReadResult?.tensorInfo,
metadataSize: headerReadResult.headerSize + initialOffset,
tensorInfoSize: tensorReadResult?.tensorInfoSize,
tensorDataOffset: tensorReadResult?.tensorDataOffset
};
}
_readGgufValue(type, offset) {
const readOffset = GgufReadOffset.resolveReadOffset(offset);
switch (type) {
case GgufValueType.Uint8: return this._fileReader.readUint8(readOffset);
case GgufValueType.Int8: return this._fileReader.readInt8(readOffset);
case GgufValueType.Uint16: return this._fileReader.readUint16(readOffset);
case GgufValueType.Int16: return this._fileReader.readInt16(readOffset);
case GgufValueType.Uint32: return this._fileReader.readUint32(readOffset);
case GgufValueType.Int32: return this._fileReader.readInt32(readOffset);
case GgufValueType.Float32: return this._fileReader.readFloat32(readOffset);
case GgufValueType.Bool: return this._fileReader.readBool(readOffset);
case GgufValueType.String: return this._readStringValue(readOffset);
case GgufValueType.Uint64: return this._fileReader.readUint64(readOffset);
case GgufValueType.Int64: return this._fileReader.readInt64(readOffset);
case GgufValueType.Float64: return this._fileReader.readFloat64(readOffset);
}
if (type === GgufValueType.Array) {
return transformPromisablesInOrder([
() => this._fileReader.readUint32(readOffset),
() => this._fileReader.readUint64(readOffset)
], ([arrayType, arrayLength]) => {
const arrayValues = [];
let i = 0;
return promisableLoop({
condition: () => i < arrayLength,
callback: () => {
return transformPromisable(this._readGgufValue(arrayType, readOffset), (value) => {
arrayValues.push(value);
});
},
afterthought: () => void i++,
returnValue: () => arrayValues
});
});
}
throw new UnsupportedGgufValueTypeError(type);
}
_readStringValue(offset) {
return this._fileReader.readString(offset);
}
async _readRawHeader(readOffset) {
const initialOffset = readOffset.offset;
const tensorCountAndMetadataKVCountPromisable = transformPromisablesInOrder([
() => this._fileReader.readUint64(readOffset),
() => transformPromisable(this._fileReader.readUint64(readOffset), Number)
]);
const [tensorCount, metadataKVCount] = tensorCountAndMetadataKVCountPromisable instanceof Promise
? await tensorCountAndMetadataKVCountPromisable
: tensorCountAndMetadataKVCountPromisable;
const metadata = {};
let i = 0;
return promisableLoop({
condition: () => i < metadataKVCount,
callback: () => {
return transformPromisablesInOrder([
() => this._readStringValue(readOffset),
() => this._fileReader.readUint32(readOffset)
], ([keyResult, valueType]) => {
return transformPromisable(this._readGgufValue(valueType, readOffset), (value) => {
metadata[keyResult] = value;
});
});
},
afterthought: () => void i++,
returnValue: () => ({
tensorCount: GgufFileReader.castNumberIfSafe(tensorCount),
metadata: metadata,
headerSize: readOffset.offset - initialOffset
})
});
}
_readTensorInfo(tensorCount, readOffset, ggufAlignment) {
const initialOffset = readOffset.offset;
const tensorInfo = [];
let i = 0n;
return promisableLoop({
condition: () => i < BigInt(tensorCount),
callback: () => {
const dimensions = [];
return transformPromisablesInOrder([
() => this._readStringValue(readOffset),
() => this._fileReader.readUint32(readOffset)
], ([name, dimensionsNumber]) => {
let d = 0;
return promisableLoop({
condition: () => d < dimensionsNumber,
callback: () => {
return transformPromisable(this._fileReader.readUint64(readOffset), (dimension) => {
dimensions.push(GgufFileReader.castNumberIfSafe(dimension));
});
},
afterthought: () => void d++,
returnValue: () => {
return transformPromisablesInOrder([
() => this._fileReader.readUint32(readOffset),
() => this._fileReader.readUint64(readOffset)
], ([ggmlType, offset]) => {
tensorInfo.push({
name,
dimensions,
ggmlType: ggmlType,
offset: GgufFileReader.castNumberIfSafe(offset),
fileOffset: 0, // will be set later
filePart: 1 // will be updated later if needed
});
});
}
});
});
},
afterthought: () => void i++,
returnValue: () => {
const fileTensorDataOffset = alignOffset(readOffset.offset, ggufAlignment);
for (const tensor of tensorInfo)
tensor.fileOffset = typeof tensor.offset === "bigint"
? BigInt(fileTensorDataOffset) + tensor.offset
: fileTensorDataOffset + tensor.offset;
return {
tensorInfo,
tensorInfoSize: readOffset.offset - initialOffset,
tensorDataOffset: fileTensorDataOffset
};
}
});
}
}
function alignOffset(offset, alignment) {
return offset + (alignment - (offset % alignment)) % alignment;
}
//# sourceMappingURL=GgufV2Parser.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
import { GgufV2Parser } from "./GgufV2Parser.js";
export declare class GgufV3Parser extends GgufV2Parser {
}

View File

@@ -0,0 +1,4 @@
import { GgufV2Parser } from "./GgufV2Parser.js";
export class GgufV3Parser extends GgufV2Parser {
}
//# sourceMappingURL=GgufV3Parser.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"GgufV3Parser.js","sourceRoot":"","sources":["../../../src/gguf/parser/GgufV3Parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C,MAAM,OAAO,YAAa,SAAQ,YAAY;CAE7C"}

View File

@@ -0,0 +1,8 @@
import { GgufFileReader } from "../fileReaders/GgufFileReader.js";
import { GgufFileInfo } from "../types/GgufFileInfoTypes.js";
export declare function parseGguf({ fileReader, readTensorInfo, ignoreKeys, logWarnings }: {
fileReader: GgufFileReader;
readTensorInfo?: boolean;
ignoreKeys?: string[];
logWarnings?: boolean;
}): Promise<GgufFileInfo>;

View File

@@ -0,0 +1,61 @@
import { InvalidGgufMagicError } from "../errors/InvalidGgufMagicError.js";
import { getConsoleLogPrefix } from "../../utils/getConsoleLogPrefix.js";
import { UnsupportedError } from "../../utils/UnsupportedError.js";
import { GgufReadOffset } from "../utils/GgufReadOffset.js";
import { getGgufMetadataArchitectureData } from "../utils/getGgufMetadataArchitectureData.js";
import { GgufV2Parser } from "./GgufV2Parser.js";
import { GgufV3Parser } from "./GgufV3Parser.js";
const ggufMagic = "GGUF";
export async function parseGguf({ fileReader, readTensorInfo = true, ignoreKeys = [], logWarnings = true }) {
const readOffset = new GgufReadOffset(0);
const magicAndVersion = await parseMagicAndVersion(fileReader, readOffset);
const ggufInfo = await parseGgufUsingASpecificVersionParser({
fileReader,
readTensorInfo,
ignoreKeys,
version: magicAndVersion.version,
readOffset,
logWarnings
});
const architectureMetadata = getGgufMetadataArchitectureData(ggufInfo.metadata);
return {
version: magicAndVersion.version,
tensorCount: ggufInfo.tensorCount,
metadata: ggufInfo.metadata,
architectureMetadata: architectureMetadata,
tensorInfo: ggufInfo.tensorInfo,
metadataSize: ggufInfo.metadataSize,
splicedParts: 1,
totalTensorInfoSize: ggufInfo.tensorInfoSize,
totalTensorCount: ggufInfo.tensorCount,
totalMetadataSize: ggufInfo.metadataSize,
fullTensorInfo: ggufInfo.tensorInfo,
tensorInfoSize: ggufInfo.tensorInfoSize
};
}
async function parseMagicAndVersion(fileReader, readOffset) {
const fileMagicText = await fileReader.readStringWithLength(readOffset, ggufMagic.length);
if (fileMagicText !== ggufMagic)
throw new InvalidGgufMagicError(ggufMagic, fileMagicText);
const version = await fileReader.readUint32(readOffset);
return {
magic: ggufMagic,
version
};
}
async function parseGgufUsingASpecificVersionParser(specificVersionParserOptions) {
switch (specificVersionParserOptions.version) {
case 1:
throw new UnsupportedError("GGUF version 1 is not supported by llama.cpp anymore");
case 2:
return await (new GgufV2Parser(specificVersionParserOptions)).parse();
case 3:
return await (new GgufV3Parser(specificVersionParserOptions)).parse();
default:
if (specificVersionParserOptions.logWarnings)
console.warn(getConsoleLogPrefix() +
`Unsupported GGUF version "${specificVersionParserOptions.version}". Reading the file as GGUF version 3`);
return await (new GgufV3Parser(specificVersionParserOptions)).parse();
}
}
//# sourceMappingURL=parseGguf.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parseGguf.js","sourceRoot":"","sources":["../../../src/gguf/parser/parseGguf.ts"],"names":[],"mappings":"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"}