Skip to content

Commit c0a43bc

Browse files
author
Mishig
authored
[gguf & st] parse shard filenames in typed function (#631)
follow up to #627 (review) > why not a typed function fn(filename) that returns all the data in a typed manner instead of the regex 🙈 . > Currently in the next version of HF.js we can change the regex to something else, removing or renaming the groups, and on moon's side we'd have no clue. No compiler warning or anything.
1 parent 08f6eaa commit c0a43bc

File tree

4 files changed

+48
-13
lines changed

4 files changed

+48
-13
lines changed

packages/gguf/src/gguf.spec.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, it } from "vitest";
2-
import { GGMLQuantizationType, RE_GGUF_SHARD_FILE, gguf } from "./gguf";
2+
import { GGMLQuantizationType, gguf, parseGgufShardFile } from "./gguf";
33

44
const URL_LLAMA = "https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGUF/resolve/191239b/llama-2-7b-chat.Q2_K.gguf";
55
const URL_MISTRAL_7B =
@@ -223,11 +223,10 @@ describe("gguf", () => {
223223

224224
it("should detect sharded gguf filename", async () => {
225225
const ggufPath = "grok-1/grok-1-q4_0-00003-of-00009.gguf"; // https://huggingface.co/ggml-org/models/blob/fcf344adb9686474c70e74dd5e55465e9e6176ef/grok-1/grok-1-q4_0-00003-of-00009.gguf
226-
const match = ggufPath.match(RE_GGUF_SHARD_FILE);
226+
const ggufShardFileInfo = parseGgufShardFile(ggufPath);
227227

228-
expect(RE_GGUF_SHARD_FILE.test(ggufPath)).toEqual(true);
229-
expect(match?.groups?.prefix).toEqual("grok-1/grok-1-q4_0");
230-
expect(match?.groups?.shard).toEqual("00003");
231-
expect(match?.groups?.total).toEqual("00009");
228+
expect(ggufShardFileInfo?.prefix).toEqual("grok-1/grok-1-q4_0");
229+
expect(ggufShardFileInfo?.shard).toEqual("00003");
230+
expect(ggufShardFileInfo?.total).toEqual("00009");
232231
});
233232
});

packages/gguf/src/gguf.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@ export { GGUF_QUANT_DESCRIPTIONS } from "./quant-descriptions";
88
export const RE_GGUF_FILE = /\.gguf$/;
99
export const RE_GGUF_SHARD_FILE = /^(?<prefix>.*?)-(?<shard>\d{5})-of-(?<total>\d{5})\.gguf$/;
1010

11+
export interface GgufShardFileInfo {
12+
prefix: string;
13+
shard: string;
14+
total: string;
15+
}
16+
17+
export function parseGgufShardFile(filename: string): GgufShardFileInfo | null {
18+
const match = RE_GGUF_SHARD_FILE.exec(filename);
19+
if (match && match.groups) {
20+
return {
21+
prefix: match.groups["prefix"],
22+
shard: match.groups["shard"],
23+
total: match.groups["total"],
24+
};
25+
}
26+
return null;
27+
}
28+
1129
const isVersion = (version: number): version is Version => version === 1 || version === 2 || version === 3;
1230

1331
/**

packages/hub/src/lib/parse-safetensors-metadata.spec.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { assert, it, describe } from "vitest";
2-
import { RE_SAFETENSORS_SHARD_FILE, parseSafetensorsMetadata } from "./parse-safetensors-metadata";
2+
import { parseSafetensorsMetadata, parseSafetensorsShardFile } from "./parse-safetensors-metadata";
33
import { sum } from "../utils/sum";
44

55
describe("parseSafetensorsMetadata", () => {
@@ -112,12 +112,11 @@ describe("parseSafetensorsMetadata", () => {
112112

113113
it("should detect sharded safetensors filename", async () => {
114114
const safetensorsFilename = "model_00005-of-00072.safetensors"; // https://huggingface.co/bigscience/bloom/blob/4d8e28c67403974b0f17a4ac5992e4ba0b0dbb6f/model_00005-of-00072.safetensors
115-
const match = safetensorsFilename.match(RE_SAFETENSORS_SHARD_FILE);
115+
const safetensorsShardFileInfo = parseSafetensorsShardFile(safetensorsFilename);
116116

117-
assert.strictEqual(RE_SAFETENSORS_SHARD_FILE.test(safetensorsFilename), true);
118-
assert.strictEqual(match?.groups?.prefix, "model_");
119-
assert.strictEqual(match?.groups?.basePrefix, "model");
120-
assert.strictEqual(match?.groups?.shard, "00005");
121-
assert.strictEqual(match?.groups?.total, "00072");
117+
assert.strictEqual(safetensorsShardFileInfo?.prefix, "model_");
118+
assert.strictEqual(safetensorsShardFileInfo?.basePrefix, "model");
119+
assert.strictEqual(safetensorsShardFileInfo?.shard, "00005");
120+
assert.strictEqual(safetensorsShardFileInfo?.total, "00072");
122121
});
123122
});

packages/hub/src/lib/parse-safetensors-metadata.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,25 @@ export const RE_SAFETENSORS_FILE = /\.safetensors$/;
1616
export const RE_SAFETENSORS_INDEX_FILE = /\.safetensors\.index\.json$/;
1717
export const RE_SAFETENSORS_SHARD_FILE =
1818
/^(?<prefix>(?<basePrefix>.*?)[_-])(?<shard>\d{5})-of-(?<total>\d{5})\.safetensors$/;
19+
export interface SafetensorsShardFileInfo {
20+
prefix: string;
21+
basePrefix: string;
22+
shard: string;
23+
total: string;
24+
}
25+
export function parseSafetensorsShardFile(filename: string): SafetensorsShardFileInfo | null {
26+
const match = RE_SAFETENSORS_SHARD_FILE.exec(filename);
27+
if (match && match.groups) {
28+
return {
29+
prefix: match.groups["prefix"],
30+
basePrefix: match.groups["basePrefix"],
31+
shard: match.groups["shard"],
32+
total: match.groups["total"],
33+
};
34+
}
35+
return null;
36+
}
37+
1938
const PARALLEL_DOWNLOADS = 20;
2039
const MAX_HEADER_LENGTH = 25_000_000;
2140

0 commit comments

Comments
 (0)