Skip to content

Commit fecacf3

Browse files
committed
test: short URIs
1 parent 078d45c commit fecacf3

File tree

2 files changed

+217
-3
lines changed

2 files changed

+217
-3
lines changed

src/utils/parseModelUri.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ async function fetchHuggingFaceModelManifest({
205205
if ((response.status >= 500 || response.status === 429 || response.status === 401) && headersToTry.length > 0)
206206
continue;
207207

208+
if (response.status === 400 || response.status === 404)
209+
throw new Error(`Cannot get quantization "${modelTag}" for model "hf:${user}/${model}" or it does not exist`);
210+
208211
if (!response.ok)
209212
throw new Error(`Failed to fetch manifest for ${JSON.stringify(fullUri)}: ${response.status} ${response.statusText}`);
210213

@@ -240,6 +243,9 @@ function parseHuggingFaceUriContent(uri: string, fullUri: string): ParsedModelUr
240243
const actualTag = tagParts.length > 0
241244
? [tag, ...tagParts].join(":").trimEnd()
242245
: (tag ?? "").trimEnd();
246+
const resolvedTag = ggufQuantNames.has(actualTag.toUpperCase())
247+
? actualTag.toUpperCase()
248+
: actualTag;
243249

244250
if (actualModel == null || actualModel === "" || user === "")
245251
throw new Error(`Invalid Hugging Face URI: ${fullUri}`);
@@ -251,7 +257,7 @@ function parseHuggingFaceUriContent(uri: string, fullUri: string): ParsedModelUr
251257
const filePrefix = buildHuggingFaceFilePrefix(user, actualModel, defaultHuggingFaceBranch, [], baseFilename + ".gguf");
252258
return {
253259
type: "unresolved",
254-
uri: `hf:${user}/${actualModel}${actualTag !== "" ? `:${actualTag}` : ""}`,
260+
uri: `hf:${user}/${actualModel}${resolvedTag !== "" ? `:${resolvedTag}` : ""}`,
255261
filePrefix,
256262
baseFilename,
257263
possibleFullFilenames: [
@@ -264,7 +270,7 @@ function parseHuggingFaceUriContent(uri: string, fullUri: string): ParsedModelUr
264270
type: "hf",
265271
user,
266272
model: actualModel,
267-
tag: actualTag
273+
tag: resolvedTag
268274
}
269275
};
270276
}

test/standalone/utils/parseModelUri.test.ts

Lines changed: 209 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {fileURLToPath} from "url";
22
import {describe, expect, test} from "vitest";
3-
import {parseModelUri} from "../../../src/utils/parseModelUri.js";
3+
import {parseModelUri, resolveParsedModelUri} from "../../../src/utils/parseModelUri.js";
44

55
const __filename = fileURLToPath(import.meta.url);
66

@@ -32,6 +32,7 @@ describe("utils", () => {
3232
"filename": "Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
3333
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
3434
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf?download=true",
35+
"type": "resolved",
3536
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
3637
}
3738
`);
@@ -49,6 +50,7 @@ describe("utils", () => {
4950
"filename": "Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
5051
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
5152
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf?download=true",
53+
"type": "resolved",
5254
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
5355
}
5456
`);
@@ -66,6 +68,7 @@ describe("utils", () => {
6668
"filename": "Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
6769
"fullFilename": "hf_bartowski_Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
6870
"resolvedUrl": "https://huggingface.co/bartowski/Meta-Llama-3.1-70B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-70B-Instruct-Q5_K_L/Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf?download=true",
71+
"type": "resolved",
6972
"uri": "hf:bartowski/Meta-Llama-3.1-70B-Instruct-GGUF/Meta-Llama-3.1-70B-Instruct-Q5_K_L/Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
7073
}
7174
`);
@@ -83,6 +86,7 @@ describe("utils", () => {
8386
"filename": "Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
8487
"fullFilename": "hf_bartowski_Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
8588
"resolvedUrl": "https://huggingface.co/bartowski/Meta-Llama-3.1-70B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-70B-Instruct-Q5_K_L/Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf?download=true",
89+
"type": "resolved",
8690
"uri": "hf:bartowski/Meta-Llama-3.1-70B-Instruct-GGUF/Meta-Llama-3.1-70B-Instruct-Q5_K_L/Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
8791
}
8892
`);
@@ -100,6 +104,7 @@ describe("utils", () => {
100104
"filename": "Meta-Llama-3.1-70B-Instruct.Q8_0.gguf",
101105
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-70B-Instruct.Q8_0.gguf",
102106
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-70B-Instruct.Q8_0.gguf.part1of2?download=true",
107+
"type": "resolved",
103108
"uri": "hf:mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF/Meta-Llama-3.1-70B-Instruct.Q8_0.gguf.part1of2",
104109
}
105110
`);
@@ -114,6 +119,7 @@ describe("utils", () => {
114119
"filename": "Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
115120
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
116121
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf?download=true",
122+
"type": "resolved",
117123
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
118124
}
119125
`);
@@ -128,6 +134,7 @@ describe("utils", () => {
128134
"filename": "Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
129135
"fullFilename": "hf_bartowski_Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
130136
"resolvedUrl": "https://huggingface.co/bartowski/Meta-Llama-3.1-70B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-70B-Instruct-Q5_K_L/Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf?download=true",
137+
"type": "resolved",
131138
"uri": "hf:bartowski/Meta-Llama-3.1-70B-Instruct-GGUF/Meta-Llama-3.1-70B-Instruct-Q5_K_L/Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf",
132139
}
133140
`);
@@ -142,9 +149,210 @@ describe("utils", () => {
142149
"filename": "Meta-Llama-3.1-70B-Instruct.Q8_0.gguf",
143150
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-70B-Instruct.Q8_0.gguf",
144151
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-70B-Instruct.Q8_0.gguf.part1of2?download=true",
152+
"type": "resolved",
145153
"uri": "hf:mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF/Meta-Llama-3.1-70B-Instruct.Q8_0.gguf.part1of2",
146154
}
147155
`);
148156
});
157+
158+
test("Hugging Face simple URI is resolved", async () => {
159+
const parsedModelUri = parseModelUri("hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M");
160+
161+
expect(parsedModelUri).toMatchInlineSnapshot(`
162+
{
163+
"baseFilename": "Meta-Llama-3.1-8B-Instruct",
164+
"filePrefix": "hf_mradermacher_",
165+
"possibleFullFilenames": [
166+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
167+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M-00001-of-{:
168+
{number}
169+
:}.gguf",
170+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.gguf",
171+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct-00001-of-{:
172+
{number}
173+
:}.gguf",
174+
],
175+
"resolveDetails": {
176+
"model": "Meta-Llama-3.1-8B-Instruct-GGUF",
177+
"tag": "Q4_K_M",
178+
"type": "hf",
179+
"user": "mradermacher",
180+
},
181+
"type": "unresolved",
182+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M",
183+
}
184+
`);
185+
186+
const resolvedUri = await resolveParsedModelUri(parsedModelUri);
187+
expect(resolvedUri).toMatchInlineSnapshot(`
188+
{
189+
"filePrefix": "hf_mradermacher_",
190+
"filename": "Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
191+
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
192+
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf?download=true",
193+
"type": "resolved",
194+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M",
195+
}
196+
`);
197+
});
198+
199+
test("Hugging Face simple URI is resolved - lowercase quant", async () => {
200+
const parsedModelUri = parseModelUri("hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF:q4_k_m");
201+
202+
expect(parsedModelUri).toMatchInlineSnapshot(`
203+
{
204+
"baseFilename": "Meta-Llama-3.1-8B-Instruct",
205+
"filePrefix": "hf_mradermacher_",
206+
"possibleFullFilenames": [
207+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
208+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M-00001-of-{:
209+
{number}
210+
:}.gguf",
211+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.gguf",
212+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct-00001-of-{:
213+
{number}
214+
:}.gguf",
215+
],
216+
"resolveDetails": {
217+
"model": "Meta-Llama-3.1-8B-Instruct-GGUF",
218+
"tag": "Q4_K_M",
219+
"type": "hf",
220+
"user": "mradermacher",
221+
},
222+
"type": "unresolved",
223+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M",
224+
}
225+
`);
226+
227+
const resolvedUri = await resolveParsedModelUri(parsedModelUri);
228+
expect(resolvedUri).toMatchInlineSnapshot(`
229+
{
230+
"filePrefix": "hf_mradermacher_",
231+
"filename": "Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
232+
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
233+
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf?download=true",
234+
"type": "resolved",
235+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M",
236+
}
237+
`);
238+
});
239+
240+
test("Hugging Face simple URI is resolved 2", async () => {
241+
const parsedModelUri = parseModelUri("hf:bartowski/Meta-Llama-3.1-70B-Instruct-GGUF:Q5_K_L");
242+
243+
expect(parsedModelUri).toMatchInlineSnapshot(`
244+
{
245+
"baseFilename": "Meta-Llama-3.1-70B-Instruct",
246+
"filePrefix": "hf_bartowski_",
247+
"possibleFullFilenames": [
248+
"hf_bartowski_Meta-Llama-3.1-70B-Instruct.Q4_K_M.gguf",
249+
"hf_bartowski_Meta-Llama-3.1-70B-Instruct.Q4_K_M-00001-of-{:
250+
{number}
251+
:}.gguf",
252+
"hf_bartowski_Meta-Llama-3.1-70B-Instruct.gguf",
253+
"hf_bartowski_Meta-Llama-3.1-70B-Instruct-00001-of-{:
254+
{number}
255+
:}.gguf",
256+
],
257+
"resolveDetails": {
258+
"model": "Meta-Llama-3.1-70B-Instruct-GGUF",
259+
"tag": "Q5_K_L",
260+
"type": "hf",
261+
"user": "bartowski",
262+
},
263+
"type": "unresolved",
264+
"uri": "hf:bartowski/Meta-Llama-3.1-70B-Instruct-GGUF:Q5_K_L",
265+
}
266+
`);
267+
268+
const resolvedUri = await resolveParsedModelUri(parsedModelUri);
269+
expect(resolvedUri).toMatchInlineSnapshot(`
270+
{
271+
"filePrefix": "hf_bartowski_",
272+
"filename": "Meta-Llama-3.1-70B-Instruct.Q5_K_L-00001-of-00002.gguf",
273+
"fullFilename": "hf_bartowski_Meta-Llama-3.1-70B-Instruct.Q5_K_L-00001-of-00002.gguf",
274+
"resolvedUrl": "https://huggingface.co/bartowski/Meta-Llama-3.1-70B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-70B-Instruct-Q5_K_L/Meta-Llama-3.1-70B-Instruct-Q5_K_L-00001-of-00002.gguf?download=true",
275+
"type": "resolved",
276+
"uri": "hf:bartowski/Meta-Llama-3.1-70B-Instruct-GGUF:Q5_K_L",
277+
}
278+
`);
279+
});
280+
281+
test("Hugging Face simple URI is resolved 3", async () => {
282+
const parsedModelUri = parseModelUri("hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF");
283+
284+
expect(parsedModelUri).toMatchInlineSnapshot(`
285+
{
286+
"baseFilename": "Meta-Llama-3.1-8B-Instruct",
287+
"filePrefix": "hf_mradermacher_",
288+
"possibleFullFilenames": [
289+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
290+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M-00001-of-{:
291+
{number}
292+
:}.gguf",
293+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.gguf",
294+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct-00001-of-{:
295+
{number}
296+
:}.gguf",
297+
],
298+
"resolveDetails": {
299+
"model": "Meta-Llama-3.1-8B-Instruct-GGUF",
300+
"tag": "",
301+
"type": "hf",
302+
"user": "mradermacher",
303+
},
304+
"type": "unresolved",
305+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF",
306+
}
307+
`);
308+
309+
const resolvedUri = await resolveParsedModelUri(parsedModelUri);
310+
expect(resolvedUri).toMatchInlineSnapshot(`
311+
{
312+
"filePrefix": "hf_mradermacher_",
313+
"filename": "Meta-Llama-3.1-8B-Instruct.IQ3_M.gguf",
314+
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-8B-Instruct.IQ3_M.gguf",
315+
"resolvedUrl": "https://huggingface.co/mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct.IQ3_M.gguf?download=true",
316+
"type": "resolved",
317+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF",
318+
}
319+
`);
320+
});
321+
322+
test("Hugging Face simple URI is resolved 4", async () => {
323+
const parsedModelUri = parseModelUri("hf:mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF:Q8_0");
324+
325+
expect(parsedModelUri).toMatchInlineSnapshot(`
326+
{
327+
"baseFilename": "Meta-Llama-3.1-70B-Instruct",
328+
"filePrefix": "hf_mradermacher_",
329+
"possibleFullFilenames": [
330+
"hf_mradermacher_Meta-Llama-3.1-70B-Instruct.Q4_K_M.gguf",
331+
"hf_mradermacher_Meta-Llama-3.1-70B-Instruct.Q4_K_M-00001-of-{:
332+
{number}
333+
:}.gguf",
334+
"hf_mradermacher_Meta-Llama-3.1-70B-Instruct.gguf",
335+
"hf_mradermacher_Meta-Llama-3.1-70B-Instruct-00001-of-{:
336+
{number}
337+
:}.gguf",
338+
],
339+
"resolveDetails": {
340+
"model": "Meta-Llama-3.1-70B-Instruct-GGUF",
341+
"tag": "Q8_0",
342+
"type": "hf",
343+
"user": "mradermacher",
344+
},
345+
"type": "unresolved",
346+
"uri": "hf:mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF:Q8_0",
347+
}
348+
`);
349+
350+
try {
351+
await resolveParsedModelUri(parsedModelUri);
352+
expect.unreachable("This quantization cannot be resolved due to being binary split");
353+
} catch (err) {
354+
expect(err).toMatchInlineSnapshot('[Error: Cannot get quantization "Q8_0" for model "hf:mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF" or it does not exist]');
355+
}
356+
});
149357
});
150358
});

0 commit comments

Comments
 (0)