Skip to content

👾Fix chunk count not incrementing when parsing additional chunks in a local file #767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

ryan-the-crayon
Copy link
Contributor

When parsing a local GGUF and the metadata section does not fit in the same chunk, the parser would try to load more chunks. However, in the local file implementation range view, the chunk count is not incremented, resulting it not actually loading in more data.

@mishig25
Copy link
Collaborator

cc: @ngxson

@ngxson
Copy link
Member

ngxson commented Jun 20, 2024

LGTM. Thanks! I don't understand why I missed this line of code 👀

@mishig25
Copy link
Collaborator

@ryan-the-crayon thanks a lot for the contribution! Anyway, you can add a test case ?

it("should parse a local file", async () => {
// download the file and save to .cache folder
if (!fs.existsSync(".cache")) {
fs.mkdirSync(".cache");
}
const res = await fetch(URL_V1);
const arrayBuf = await res.arrayBuffer();
fs.writeFileSync(".cache/model.gguf", Buffer.from(arrayBuf));
const { metadata } = await gguf(".cache/model.gguf", { allowLocalFile: true });
expect(metadata).toMatchObject({ "general.name": "tinyllamas-stories-260k" });
});

@ngxson
Copy link
Member

ngxson commented Jun 20, 2024

FYI, I made a gguf with 32MB of metadata (metadata usually takes less than 2MB): https://huggingface.co/ngxson/test_gguf_models/blob/main/gguf_test_big_metadata.gguf

The test would be:

const parsedGguf = await gguf(".cache/model.gguf", { allowLocalFile: true });
const { metadata } = (parsedGguf as GGUFParseOutput<{ strict: false }>); // custom metadata arch, no need for typing
expect(metadata['dummy.1']).toBeDefined(); // first metadata in the list
expect(metadata['dummy.32767']).toBeDefined(); // last metadata in the list
CPP code to generate gguf
#include "ggml.h"
#include <cstring>
#include <string>

int main(int argc, char ** argv) {
    struct gguf_context * ctx = gguf_init_empty();
    gguf_set_val_str(ctx, "general.architecture", "gguf_test_big_metadata");

    char str1kb[1025];
    std::memset(str1kb, 'A', 1024);
    str1kb[1024] = '\0';
    for (int i = 0; i < 32 * 1024; i++) {
        gguf_set_val_str(ctx, ("dummy." + std::to_string(i)).c_str(), str1kb);
    }

    gguf_write_to_file(ctx, "gguf_test_big_metadata.gguf", false);
    gguf_free(ctx);
}

@mishig25 mishig25 merged commit 70a27aa into huggingface:main Jun 21, 2024
4 checks passed
@mishig25
Copy link
Collaborator

@ryan-the-crayon @ngxson merged and the new version of @huggingface/gguf.js with the fix is released

mishig25 pushed a commit that referenced this pull request Jun 28, 2024
Ref comment:
#767 (comment)

This file have 32MB of just metadata (no tensor), can be useful for
testing or benchmarking.

Due to its large size, running the download process inside the test case
may cause timeout (so I moved it to `beforeAll`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants