Spaces:
Running
Running
coyotte508
commited on
Commit
·
b8ecebf
1
Parent(s):
346553f
full test suite
Browse files- .vscode/settings.json +3 -0
- app.js +157 -16
- index.html +98 -33
.vscode/settings.json
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"editor.formatOnSave": true
|
3 |
+
}
|
app.js
CHANGED
@@ -1,26 +1,27 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
4 |
|
5 |
const lfsContent = "0123456789".repeat(1_000_000);
|
6 |
|
7 |
const XetBlobs = {
|
8 |
// "hub-unbundled": XetBlobUnbundled,
|
9 |
"hub-esm": XetBlobEsm,
|
10 |
-
|
11 |
-
}
|
12 |
|
13 |
async function test(id) {
|
14 |
const blob = new Blob([lfsContent]);
|
15 |
|
16 |
try {
|
17 |
const blob = new XetBlobs[id]({
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
});
|
25 |
|
26 |
const text = await blob.slice(10, 22).text();
|
@@ -29,8 +30,148 @@ async function test(id) {
|
|
29 |
document.getElementById(id).textContent = err.message;
|
30 |
}
|
31 |
}
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import {
|
2 |
+
__internal_XetBlob as XetBlob,
|
3 |
+
__internal_sha256,
|
4 |
+
} from "@huggingface/hub";
|
5 |
|
6 |
const lfsContent = "0123456789".repeat(1_000_000);
|
7 |
|
8 |
const XetBlobs = {
|
9 |
// "hub-unbundled": XetBlobUnbundled,
|
10 |
"hub-esm": XetBlobEsm,
|
11 |
+
hub: XetBlob,
|
12 |
+
};
|
13 |
|
14 |
async function test(id) {
|
15 |
const blob = new Blob([lfsContent]);
|
16 |
|
17 |
try {
|
18 |
const blob = new XetBlobs[id]({
|
19 |
+
repo: {
|
20 |
+
type: "model",
|
21 |
+
name: "celinah/xet-experiments",
|
22 |
+
},
|
23 |
+
hash: "7b3b6d07673a88cf467e67c1f7edef1a8c268cbf66e9dd9b0366322d4ab56d9b",
|
24 |
+
size: 5_234_139_343,
|
25 |
});
|
26 |
|
27 |
const text = await blob.slice(10, 22).text();
|
|
|
30 |
document.getElementById(id).textContent = err.message;
|
31 |
}
|
32 |
}
|
33 |
+
|
34 |
+
async function checkRange(n) {
|
35 |
+
// Get selected option
|
36 |
+
const select = document.getElementById("file");
|
37 |
+
const option = select.options[select.selectedIndex];
|
38 |
+
|
39 |
+
// hash is in data-xet-hash attribute
|
40 |
+
const xetHash = option.getAttribute("data-xet-hash");
|
41 |
+
const sha = option.getAttribute("data-sha");
|
42 |
+
const size = +option.getAttribute("data-size");
|
43 |
+
const path = `https://huggingface.co/celinah/xet-experiments/resolve/main/${option.value}`;
|
44 |
+
|
45 |
+
const output = document.getElementById("output");
|
46 |
+
output.textContent = "";
|
47 |
+
|
48 |
+
const blob = new XetBlob({
|
49 |
+
repo: {
|
50 |
+
type: "model",
|
51 |
+
name: "celinah/xet-experiments",
|
52 |
+
},
|
53 |
+
hash: xetHash,
|
54 |
+
size,
|
55 |
+
});
|
56 |
+
|
57 |
+
const [own, bridge] = await Promise.all([
|
58 |
+
blob.slice(0, n).arrayBuffer(),
|
59 |
+
fetch(path, { headers: { Range: `bytes=0-${n - 1}` } }).then((res) =>
|
60 |
+
res.arrayBuffer()
|
61 |
+
),
|
62 |
+
]);
|
63 |
+
|
64 |
+
output.textContent += `Own: ${own.byteLength}\nBridge: ${bridge.byteLength}\n`;
|
65 |
+
// Check if the first n bytes are the same
|
66 |
+
const array1 = new Uint8Array(own);
|
67 |
+
const array2 = new Uint8Array(bridge);
|
68 |
+
|
69 |
+
let different = false;
|
70 |
+
for (let i = 0; i < n; i++) {
|
71 |
+
if (array1[i] !== array2[i]) {
|
72 |
+
output.textContent += `Difference at ${i}\n`;
|
73 |
+
different = true;
|
74 |
+
break;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
if (!different) {
|
79 |
+
output.textContent += "No differences\n";
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
async function download() {
|
84 |
+
const select = document.getElementById("file");
|
85 |
+
const option = select.options[select.selectedIndex];
|
86 |
+
const xetHash = option.getAttribute("data-xet-hash");
|
87 |
+
const size = +option.getAttribute("data-size");
|
88 |
+
|
89 |
+
const output = document.getElementById("output");
|
90 |
+
output.textContent = "";
|
91 |
+
|
92 |
+
const blob = new XetBlob({
|
93 |
+
repo: {
|
94 |
+
type: "model",
|
95 |
+
name: "celinah/xet-experiments",
|
96 |
+
},
|
97 |
+
hash: xetHash,
|
98 |
+
size,
|
99 |
+
listener: (progress) => {
|
100 |
+
output.textContent += JSON.stringify(progress) + "\n";
|
101 |
+
output.textContent =
|
102 |
+
output.textContent.split("\n").slice(-1000).join("\n") + "\n";
|
103 |
+
},
|
104 |
+
});
|
105 |
+
|
106 |
+
const arrayBuffer = await blob.arrayBuffer();
|
107 |
+
const blob2 = new Blob([arrayBuffer]);
|
108 |
+
const url = URL.createObjectURL(blob2);
|
109 |
+
|
110 |
+
const a = document.createElement("a");
|
111 |
+
a.href = url;
|
112 |
+
a.download = option.value;
|
113 |
+
a.click();
|
114 |
+
}
|
115 |
+
|
116 |
+
async function checkSha() {
|
117 |
+
const select = document.getElementById("file");
|
118 |
+
const option = select.options[select.selectedIndex];
|
119 |
+
const xetHash = option.getAttribute("data-xet-hash");
|
120 |
+
const sha = option.getAttribute("data-sha");
|
121 |
+
const size = +option.getAttribute("data-size");
|
122 |
+
|
123 |
+
const output = document.getElementById("output");
|
124 |
+
output.textContent = "";
|
125 |
+
|
126 |
+
const blob = new XetBlob({
|
127 |
+
repo: {
|
128 |
+
type: "model",
|
129 |
+
name: "celinah/xet-experiments",
|
130 |
+
},
|
131 |
+
hash: xetHash,
|
132 |
+
size,
|
133 |
+
});
|
134 |
+
|
135 |
+
const iterator = __internal_sha256(blob);
|
136 |
+
|
137 |
+
while (1) {
|
138 |
+
const result = await iterator.next();
|
139 |
+
|
140 |
+
if (result.done) {
|
141 |
+
const hash = result.value;
|
142 |
+
output.textContent += `SHA: ${hash}\n`;
|
143 |
+
output.textContent += `Expected: ${sha}\n`;
|
144 |
+
output.textContent += `Match: ${hash === sha}\n`;
|
145 |
+
break;
|
146 |
+
}
|
147 |
+
|
148 |
+
output.textContent = `Progress: ${result.value * 100}%\n`;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
// On loaded, add event listeners
|
153 |
+
document.addEventListener(
|
154 |
+
"DOMContentLoaded",
|
155 |
+
() => {
|
156 |
+
document.getElementById("10kB").addEventListener("click", () => {
|
157 |
+
checkRange(10_000);
|
158 |
+
});
|
159 |
+
|
160 |
+
document.getElementById("100kB").addEventListener("click", () => {
|
161 |
+
checkRange(100_000);
|
162 |
+
});
|
163 |
+
|
164 |
+
document.getElementById("1MB").addEventListener("click", () => {
|
165 |
+
checkRange(1_000_000);
|
166 |
+
});
|
167 |
+
|
168 |
+
document.getElementById("sequential").addEventListener("click", () => {
|
169 |
+
checkRange(100_000).then(() => checkRange(1_000_000));
|
170 |
+
});
|
171 |
+
|
172 |
+
document.getElementById("download").addEventListener("click", download);
|
173 |
+
|
174 |
+
document.getElementById("sha").addEventListener("click", checkSha);
|
175 |
+
},
|
176 |
+
{ once: true }
|
177 |
+
);
|
index.html
CHANGED
@@ -1,36 +1,101 @@
|
|
1 |
<!DOCTYPE html>
|
2 |
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
</html>
|
|
|
1 |
<!DOCTYPE html>
|
2 |
<html>
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8" />
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
6 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
7 |
+
<!-- polyfill for firefox + import maps -->
|
8 |
+
<script src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
|
9 |
+
<script type="importmap">
|
10 |
+
{
|
11 |
+
"imports": {
|
12 |
+
"@huggingface/hub": "https://cdn.jsdelivr.net/npm/@huggingface/hub@1.1.0-xet.1/+esm"
|
13 |
+
}
|
14 |
+
}
|
15 |
+
</script>
|
16 |
+
<script type="module" src="./app.js"></script>
|
17 |
+
</head>
|
18 |
+
<body>
|
19 |
+
<div class="container mx-auto pt-8 flex flex-col gap-4">
|
20 |
+
<h2 class="font-bold">@huggingface/[email protected]-xet</h2>
|
21 |
+
|
22 |
+
<p>
|
23 |
+
Select a file from
|
24 |
+
<a href="https://huggingface.co/celinah/xet-experiments"
|
25 |
+
>celinah/xet-experiments</a
|
26 |
+
>
|
27 |
+
</p>
|
28 |
+
|
29 |
+
<select id="file">
|
30 |
+
<option
|
31 |
+
value="dataset1MB.zip"
|
32 |
+
data-size="1400865"
|
33 |
+
data-sha="1e5477bbbe868845be3b852d80eec2f1da6570340860668549a6dd5da0b00054"
|
34 |
+
data-xet-hash="87e19088fd7d31e4a77be3f993d85031f5ecbc8f5ad58668880516209e6ed663"
|
35 |
+
>
|
36 |
+
dataset1MB.zip (1,4MB)
|
37 |
+
</option>
|
38 |
+
<option
|
39 |
+
value="large_text.txt"
|
40 |
+
data-size="62914580"
|
41 |
+
data-xet-hash="794efea76d8cb372bbe1385d9e51c3384555f3281e629903ecb6abeff7d54eec"
|
42 |
+
data-sha="c27f98578d9363b27db0bc1cbd9c692f8e6e90ae98c38cee7bc0a88829debd17"
|
43 |
+
>
|
44 |
+
large_text.txt (62.9MB)
|
45 |
+
</option>
|
46 |
+
<option
|
47 |
+
value="model133MB.safetensors"
|
48 |
+
data-size="133610664"
|
49 |
+
data-sha="35bb6ef696cc88b3d18b7520273dfd25315f6c47d265142ba13bba38678c92b6"
|
50 |
+
data-xet-hash="bdfd0a89d314f83b7fefed034f2c61133d4b49f7e9eff920dcd4c7062e64adf0"
|
51 |
+
>
|
52 |
+
model133MB.safetensors (134MB)
|
53 |
+
</option>
|
54 |
+
<option
|
55 |
+
value="model133MB_bis.safetensors"
|
56 |
+
data-size="133610664"
|
57 |
+
data-sha="35bb6ef696cc88b3d18b7520273dfd25315f6c47d265142ba13bba38678c92b6"
|
58 |
+
data-xet-hash="bdfd0a89d314f83b7fefed034f2c61133d4b49f7e9eff920dcd4c7062e64adf0"
|
59 |
+
>
|
60 |
+
model133MB.safetensors (134MB)
|
61 |
+
</option>
|
62 |
+
<option
|
63 |
+
value="model5GB.safetensors"
|
64 |
+
data-size="5234139343"
|
65 |
+
data-sha="b933b099f335d0cc95380200bbc3d1dc4b240f0c81e6de1a192b4921142403f8"
|
66 |
+
data-xet-hash="7b3b6d07673a88cf467e67c1f7edef1a8c268cbf66e9dd9b0366322d4ab56d9b"
|
67 |
+
>
|
68 |
+
model5GB.safetensors (5.2GB)
|
69 |
+
</option>
|
70 |
+
<option
|
71 |
+
value="rand1GB_0.safetensors"
|
72 |
+
data-size="1073741824"
|
73 |
+
data-sha="5360d7847d01cad7a0d5dd9a3f87d4fb3535ab1becbc5fa7796bb81cfb16acd7"
|
74 |
+
data-xet-hash="602ffd88da44b7b1cdf94a4abfdbdcf211fe36de2c71d08b5c491fabd3fd92d8"
|
75 |
+
>
|
76 |
+
rand1GB_0.safetensors (1.1GB)
|
77 |
+
</option>
|
78 |
+
<option
|
79 |
+
value="rand500MB"
|
80 |
+
data-size="524288000"
|
81 |
+
data-sha="8059a3147859009f1841e7df52364f20891709898ebf6150e4d1685103ab7e8f"
|
82 |
+
data-xet-hash="6d73bd467f35d5b9017f8a6aa358889f10c85a4e3278497382c3d1baaba4fe5a"
|
83 |
+
>
|
84 |
+
rand500MB (524MB)
|
85 |
+
</option>
|
86 |
+
</select>
|
87 |
+
<div class="flex gap-2 flex-wrap">
|
88 |
+
<button type="button" id="10kB">Check first 10 kB</button>
|
89 |
+
<button type="button" id="100kB">Check first 100 kB</button>
|
90 |
+
<button type="button" id="1MB">Check first MB</button>
|
91 |
+
<button type="button" id="sequential">
|
92 |
+
Check 100kB then 1MB in succession
|
93 |
+
</button>
|
94 |
+
<button type="button" id="sha">Check full file's sha</button>
|
95 |
+
<button type="button" id="download">Download full file</button>
|
96 |
+
</div>
|
97 |
+
|
98 |
+
<pre id="output"></pre>
|
99 |
+
</div>
|
100 |
+
</body>
|
101 |
</html>
|