Skip to content

Commit fe477dc

Browse files
committed
feat: parse Hugging Face model card URLs into URIs
1 parent 7b56fba commit fe477dc

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/utils/parseModelUri.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ export function parseModelUri(urlOrUri: string, convertUrlToSupportedUri: boolea
5050
else if (urlOrUri.startsWith("huggingface.co/"))
5151
return parseHuggingFaceUriContent(urlOrUri.slice("huggingface.co/".length), urlOrUri);
5252

53+
if (isUrl(urlOrUri)) {
54+
const parsedUrl = new URL(urlOrUri);
55+
if (parsedUrl.hostname === "huggingface.co" || parsedUrl.hostname === "hf.co") {
56+
const pathnameParts = parsedUrl.pathname.split("/");
57+
const slashes = pathnameParts.length - 1;
58+
const [, user, model] = pathnameParts;
59+
60+
if (slashes === 2 && user != null && model != null) {
61+
return parseHuggingFaceUriContent([
62+
decodeURIComponent(user), "/", decodeURIComponent(model)
63+
].join(""), urlOrUri);
64+
}
65+
}
66+
}
67+
5368
if (convertUrlToSupportedUri && isUrl(urlOrUri)) {
5469
const parsedUrl = new URL(normalizeGgufDownloadUrl(urlOrUri));
5570
if (parsedUrl.hostname === "huggingface.co" || parsedUrl.hostname === "hf.co") {

test/standalone/utils/parseModelUri.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,47 @@ describe("utils", () => {
340340
});
341341

342342
test("Hugging Face simple URI is resolved 5", async () => {
343+
const parsedModelUri = parseModelUri("https://huggingface.co/mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF");
344+
345+
expect(parsedModelUri).toMatchInlineSnapshot(`
346+
{
347+
"baseFilename": "Meta-Llama-3.1-8B-Instruct",
348+
"filePrefix": "hf_mradermacher_",
349+
"possibleFullFilenames": [
350+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf",
351+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.Q4_K_M-00001-of-{:
352+
{number}
353+
:}.gguf",
354+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct.gguf",
355+
"hf_mradermacher_Meta-Llama-3.1-8B-Instruct-00001-of-{:
356+
{number}
357+
:}.gguf",
358+
],
359+
"resolveDetails": {
360+
"model": "Meta-Llama-3.1-8B-Instruct-GGUF",
361+
"tag": "",
362+
"type": "hf",
363+
"user": "mradermacher",
364+
},
365+
"type": "unresolved",
366+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF",
367+
}
368+
`);
369+
370+
const resolvedUri = await resolveParsedModelUri(parsedModelUri);
371+
expect(resolvedUri).toMatchInlineSnapshot(`
372+
{
373+
"filePrefix": "hf_mradermacher_",
374+
"filename": "Meta-Llama-3.1-8B-Instruct.IQ3_M.gguf",
375+
"fullFilename": "hf_mradermacher_Meta-Llama-3.1-8B-Instruct.IQ3_M.gguf",
376+
"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",
377+
"type": "resolved",
378+
"uri": "hf:mradermacher/Meta-Llama-3.1-8B-Instruct-GGUF",
379+
}
380+
`);
381+
});
382+
383+
test("Hugging Face simple URI is resolved 6", async () => {
343384
const parsedModelUri = parseModelUri("hf:mradermacher/Meta-Llama-3.1-70B-Instruct-GGUF:invalid");
344385

345386
expect(parsedModelUri).toMatchInlineSnapshot(`

0 commit comments

Comments
 (0)