[GGUF] metadata serialization into Uint8Arrray#1740
Merged
Conversation
coyotte508
approved these changes
Sep 10, 2025
d65989a to
54dc2e5
Compare
…variable and unnecessary whitespace. This cleanup improves code readability without altering functionality.
…or typed metadata
Collaborator
Author
|
pushed df2d0a9 , for serialize functions to return |
julien-c
reviewed
Sep 10, 2025
packages/gguf/src/gguf.spec.ts
Outdated
Comment on lines
+485
to
+487
| expect(result).toHaveProperty("littleEndian"); | ||
| expect(typeof result.littleEndian).toBe("boolean"); | ||
| // Most modern GGUF files should be little-endian |
Member
There was a problem hiding this comment.
Suggested change
| expect(result).toHaveProperty("littleEndian"); | |
| expect(typeof result.littleEndian).toBe("boolean"); | |
| // Most modern GGUF files should be little-endian |
keep things a bit more compact no?
julien-c
approved these changes
Sep 10, 2025
packages/gguf/src/gguf.ts
Outdated
| const version = typedMetadata.version.value; | ||
|
|
||
| // Start with GGUF magic number: "GGUF" | ||
| const magicNumber = new Uint8Array([0x47, 0x47, 0x55, 0x46]); |
Member
There was a problem hiding this comment.
reuse ggufMagicNumber already in the file
packages/gguf/src/gguf.ts
Outdated
| const version = typedMetadata.version.value; | ||
|
|
||
| // Start with GGUF magic number: "GGUF" | ||
| const magicNumber = new Uint8Array([0x47, 0x47, 0x55, 0x46]); |
packages/gguf/src/gguf.ts
Outdated
Comment on lines
+768
to
+773
| export function serializeGgufHeader( | ||
| typedMetadata: GGUFTypedMetadata, | ||
| tensorInfos: GGUFTensorInfo[], | ||
| options: { | ||
| /** | ||
| * Whether to use little endian byte order |
Member
There was a problem hiding this comment.
hmm why is this function so duplicated / not calling serializeTypedMetadata? let's try to reuse it
packages/gguf/src/gguf.ts
Outdated
| * @param options - Serialization options | ||
| * @returns A Uint8Array containing the serialized GGUF header data | ||
| */ | ||
| export function serializeTypedMetadata( |
Member
There was a problem hiding this comment.
Suggested change
| export function serializeTypedMetadata( | |
| export function serializeGgufMetadata( |
suggestion: more simply lilke this
mishig25
added a commit
that referenced
this pull request
Sep 19, 2025
# `buildGgufHeader`: GGUF header reconstruction with proper alignment ## 🎯 Why `serializeGgufMetadata` #1740 isn't enough **`serializeGgufMetadata`** only handles metadata serialization but **lacks critical functionality**: - ❌ **No tensor info preservation** - loses original tensor definitions - ❌ **No alignment calculation** - creates invalid memory layout - ❌ **Incomplete headers** - generates metadata-only files - ❌ **Framework incompatible** - resulting files can't be loaded ## 🚀 `buildGgufHeader`: Complete solution **`buildGgufHeader`** is a **comprehensive function** that uses `serializeGgufMetadata` internally but adds essential missing pieces: ```typescript export async function buildGgufHeader(originalFileBlob, updatedMetadata, options) { // 1. ✅ Use serializeGgufMetadata for metadata const newHeaderBytes = serializeGgufMetadata(updatedMetadata, { littleEndian: options.littleEndian, alignment, }); // 2. ✅ Preserve original tensor info (missing in serializeGgufMetadata) const originalTensorInfoBlob = originalFileBlob.slice(tensorInfoStart, tensorInfoEnd); // 3. ✅ Calculate proper alignment (missing in serializeGgufMetadata) const prePadLenNew = kvEndOffset + tensorInfoSize; const GGML_PAD = (x, n) => (x + n - 1) & ~(n - 1); const targetTensorDataOffset = GGML_PAD(prePadLenNew, alignment); const padLen = targetTensorDataOffset - prePadLenNew; // 4. ✅ Reconstruct complete, valid header return new Blob([ newHeaderBytes.slice(0, kvEndOffset), // Metadata from serializeGgufMetadata originalTensorInfoBlob, // Preserved tensor info new Uint8Array(padLen) // Correct alignment padding ]); } ``` ## 📊 Comparison | Function | Metadata | Tensor Info | Alignment | Complete Header | |----------|----------|-------------|-----------|-----------------| | `serializeGgufMetadata` | ✅ | ❌ | ❌ | ❌ | | `buildGgufHeader` | ✅ | ✅ | ✅ | ✅ | ## 🎯 Key Innovation **`buildGgufHeader` = `serializeGgufMetadata` + tensor preservation + alignment calculation** This creates **production-ready GGUF files** that maintain framework compatibility while enabling metadata updates.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR introduces function that serializes GGUF metadata/header into Uint8Arrray so that I can use #1718 to update gguf metadata on hf.co
serializeTypedMetadata()- Serialize GGUF metadata to binary formatserializeGgufHeader()- Create complete GGUF headers with metadata + tensor info + alignmentgguf()function - Now returnslittleEndianproperty for endianness detectionUsage example