Update index.html
Browse files- index.html +10 -27
index.html
CHANGED
|
@@ -25,7 +25,7 @@
|
|
| 25 |
<h4>Output</h4>
|
| 26 |
<div id="log" class="log">Loading model…</div>
|
| 27 |
<p class="muted">
|
| 28 |
-
Model: <code>Xenova/
|
| 29 |
Backend: <span id="backend">…</span>
|
| 30 |
</p>
|
| 31 |
</div>
|
|
@@ -38,37 +38,19 @@
|
|
| 38 |
const imgEl = document.getElementById('preview');
|
| 39 |
const backendEl = document.getElementById('backend');
|
| 40 |
|
| 41 |
-
//
|
| 42 |
const hasWebGPU = 'gpu' in navigator;
|
| 43 |
const device = hasWebGPU ? 'webgpu' : 'wasm';
|
| 44 |
backendEl.textContent = device.toUpperCase();
|
| 45 |
-
envEl.textContent = hasWebGPU
|
| 46 |
-
? '✅ WebGPU detected. Using GPU when possible (falls back to FP32 automatically if no shader-f16).'
|
| 47 |
-
: '⚠️ No WebGPU, falling back to WASM (CPU).';
|
| 48 |
|
| 49 |
-
//
|
| 50 |
-
|
| 51 |
-
try {
|
| 52 |
-
const adapter = await navigator.gpu.requestAdapter();
|
| 53 |
-
if (adapter && !adapter.features.has('shader-f16')) {
|
| 54 |
-
envEl.textContent += ' (no shader-f16; running in FP32)';
|
| 55 |
-
}
|
| 56 |
-
} catch { /* ignore */ }
|
| 57 |
-
}
|
| 58 |
|
| 59 |
-
//
|
| 60 |
-
let pipeline;
|
| 61 |
-
try {
|
| 62 |
-
({ pipeline } = await import('https://cdn.jsdelivr.net/npm/@huggingface/transformers@3'));
|
| 63 |
-
} catch (e) {
|
| 64 |
-
logEl.textContent = 'Failed to load Transformers.js: ' + e;
|
| 65 |
-
throw e;
|
| 66 |
-
}
|
| 67 |
-
|
| 68 |
-
// 3) Build the captioning pipeline (FP16 not required)
|
| 69 |
let captioner;
|
| 70 |
try {
|
| 71 |
-
captioner = await pipeline('image-to-text', 'Xenova/
|
| 72 |
logEl.textContent = `Model ready · device=${device}`;
|
| 73 |
runBtn.disabled = false;
|
| 74 |
} catch (e) {
|
|
@@ -76,7 +58,7 @@
|
|
| 76 |
console.error(e);
|
| 77 |
}
|
| 78 |
|
| 79 |
-
//
|
| 80 |
let imgURL = null;
|
| 81 |
fileEl.addEventListener('change', () => {
|
| 82 |
if (imgURL) URL.revokeObjectURL(imgURL);
|
|
@@ -86,7 +68,7 @@
|
|
| 86 |
imgEl.src = imgURL;
|
| 87 |
});
|
| 88 |
|
| 89 |
-
//
|
| 90 |
runBtn.addEventListener('click', async () => {
|
| 91 |
if (!captioner) return;
|
| 92 |
if (!imgURL) { logEl.textContent = 'Pick an image first.'; return; }
|
|
@@ -102,3 +84,4 @@
|
|
| 102 |
</script>
|
| 103 |
</body>
|
| 104 |
</html>
|
|
|
|
|
|
| 25 |
<h4>Output</h4>
|
| 26 |
<div id="log" class="log">Loading model…</div>
|
| 27 |
<p class="muted">
|
| 28 |
+
Model: <code>Xenova/vit-gpt2-image-captioning</code><br />
|
| 29 |
Backend: <span id="backend">…</span>
|
| 30 |
</p>
|
| 31 |
</div>
|
|
|
|
| 38 |
const imgEl = document.getElementById('preview');
|
| 39 |
const backendEl = document.getElementById('backend');
|
| 40 |
|
| 41 |
+
// Prefer WebGPU; fall back to WASM
|
| 42 |
const hasWebGPU = 'gpu' in navigator;
|
| 43 |
const device = hasWebGPU ? 'webgpu' : 'wasm';
|
| 44 |
backendEl.textContent = device.toUpperCase();
|
| 45 |
+
envEl.textContent = hasWebGPU ? '✅ WebGPU detected' : '⚠️ Using WASM (CPU)';
|
|
|
|
|
|
|
| 46 |
|
| 47 |
+
// Load Transformers.js v3
|
| 48 |
+
const { pipeline } = await import('https://cdn.jsdelivr.net/npm/@huggingface/transformers@3');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
+
// Build captioning pipeline with a model that fetches cleanly
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
let captioner;
|
| 52 |
try {
|
| 53 |
+
captioner = await pipeline('image-to-text', 'Xenova/vit-gpt2-image-captioning', { device });
|
| 54 |
logEl.textContent = `Model ready · device=${device}`;
|
| 55 |
runBtn.disabled = false;
|
| 56 |
} catch (e) {
|
|
|
|
| 58 |
console.error(e);
|
| 59 |
}
|
| 60 |
|
| 61 |
+
// Preview selected image
|
| 62 |
let imgURL = null;
|
| 63 |
fileEl.addEventListener('change', () => {
|
| 64 |
if (imgURL) URL.revokeObjectURL(imgURL);
|
|
|
|
| 68 |
imgEl.src = imgURL;
|
| 69 |
});
|
| 70 |
|
| 71 |
+
// Run captioning
|
| 72 |
runBtn.addEventListener('click', async () => {
|
| 73 |
if (!captioner) return;
|
| 74 |
if (!imgURL) { logEl.textContent = 'Pick an image first.'; return; }
|
|
|
|
| 84 |
</script>
|
| 85 |
</body>
|
| 86 |
</html>
|
| 87 |
+
|