|
<html> |
|
<head> |
|
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" /> |
|
<title>Candle Moondream Rust/WASM</title> |
|
</head> |
|
<body></body> |
|
</html> |
|
|
|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="UTF-8" /> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|
<link |
|
rel="stylesheet" |
|
href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.8.0/build/styles/default.min.css" |
|
/> |
|
<style> |
|
@import url("https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@200;300;400&family=Source+Sans+3:wght@100;200;300;400;500;600;700;800;900&display=swap"); |
|
html, |
|
body { |
|
font-family: "Source Sans 3", sans-serif; |
|
} |
|
code, |
|
output, |
|
select, |
|
pre { |
|
font-family: "Source Code Pro", monospace; |
|
} |
|
</style> |
|
<style type="text/tailwindcss"> |
|
.link { |
|
@apply underline hover:text-blue-500 hover:no-underline; |
|
} |
|
</style> |
|
<script src="https://cdn.tailwindcss.com/3.4.3"></script> |
|
<script type="module" src="./code.js"></script> |
|
</head> |
|
<body class="container max-w-4xl mx-auto p-4 text-gray-800"> |
|
<main class="grid grid-cols-1 gap-8 relative"> |
|
<span class="absolute text-5xl -ml-[1em]"> 🕯️ </span> |
|
<div> |
|
<h1 class="text-5xl font-bold">Candle Moondream 2</h1> |
|
<h2 class="text-2xl font-bold">Rust/WASM Demo</h2> |
|
<p class="max-w-lg"> |
|
<a |
|
href="https://huggingface.co/vikhyatk/moondream2" |
|
class="link" |
|
target="_blank" |
|
>Moondream 2</a |
|
> |
|
by |
|
<a |
|
href=" https://huggingface.co/vikhyatk" |
|
class="link" |
|
target="_blank" |
|
>Vik</a |
|
> |
|
and model implementation on Candle by |
|
<a |
|
href="https://huggingface.co/santiagomed" |
|
class="link" |
|
target="_blank" |
|
>Santiago Medina |
|
</a> |
|
</p> |
|
</div> |
|
|
|
<div> |
|
<p class="text-xs italic max-w-lg"> |
|
<b>Note:</b> |
|
When first run, the app will download and cache the model, which could |
|
take a few minutes. Then, the embeddings and generation will take a |
|
few minutes to start 😔. |
|
</p> |
|
</div> |
|
<div> |
|
<label for="model" class="font-medium">Models Options: </label> |
|
<select |
|
id="model" |
|
class="border-2 border-gray-500 rounded-md font-light" |
|
></select> |
|
</div> |
|
<form |
|
id="form" |
|
class="flex text-normal px-1 py-1 border border-gray-700 rounded-md items-center" |
|
> |
|
<input type="submit" hidden /> |
|
<input |
|
type="text" |
|
id="prompt" |
|
value="What is in the image?" |
|
class="font-light text-lg w-full px-3 py-2 mx-1 resize-none outline-none" |
|
placeholder="Add your prompt here..." |
|
/> |
|
<button |
|
id="run" |
|
class="bg-gray-700 hover:bg-gray-800 text-white font-normal py-2 w-16 rounded disabled:bg-gray-300 disabled:cursor-not-allowed" |
|
> |
|
Run |
|
</button> |
|
</form> |
|
|
|
<details> |
|
<summary class="font-medium cursor-pointer">Advanced Options</summary> |
|
|
|
<div class="grid grid-cols-3 max-w-md items-center gap-3 py-3"> |
|
<label class="text-sm font-medium" for="max-seq" |
|
>Maximum length |
|
</label> |
|
<input |
|
type="range" |
|
id="max-seq" |
|
name="max-seq" |
|
min="1" |
|
max="2048" |
|
step="1" |
|
value="500" |
|
oninput="this.nextElementSibling.value = Number(this.value)" |
|
/> |
|
<output |
|
class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md" |
|
> |
|
500</output |
|
> |
|
<label class="text-sm font-medium" for="temperature" |
|
>Temperature</label |
|
> |
|
<input |
|
type="range" |
|
id="temperature" |
|
name="temperature" |
|
min="0" |
|
max="2" |
|
step="0.01" |
|
value="0.00" |
|
oninput="this.nextElementSibling.value = Number(this.value).toFixed(2)" |
|
/> |
|
<output |
|
class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md" |
|
> |
|
0.00</output |
|
> |
|
<label class="text-sm font-medium" for="top-p">Top-p</label> |
|
<input |
|
type="range" |
|
id="top-p" |
|
name="top-p" |
|
min="0" |
|
max="1" |
|
step="0.01" |
|
value="1.00" |
|
oninput="this.nextElementSibling.value = Number(this.value).toFixed(2)" |
|
/> |
|
<output |
|
class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md" |
|
> |
|
1.00</output |
|
> |
|
|
|
<label class="text-sm font-medium" for="repeat_penalty" |
|
>Repeat Penalty</label |
|
> |
|
|
|
<input |
|
type="range" |
|
id="repeat_penalty" |
|
name="repeat_penalty" |
|
min="1" |
|
max="2" |
|
step="0.01" |
|
value="1.10" |
|
oninput="this.nextElementSibling.value = Number(this.value).toFixed(2)" |
|
/> |
|
<output |
|
class="text-xs w-[50px] text-center font-light px-1 py-1 border border-gray-700 rounded-md" |
|
>1.10</output |
|
> |
|
<label class="text-sm font-medium" for="seed">Seed</label> |
|
<input |
|
type="number" |
|
id="seed" |
|
name="seed" |
|
value="299792458" |
|
class="font-light border border-gray-700 text-right rounded-md p-2" |
|
/> |
|
<button |
|
id="run" |
|
onclick="document.querySelector('#seed').value = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)" |
|
class="bg-gray-700 hover:bg-gray-800 text-white font-normal py-1 w-[50px] rounded disabled:bg-gray-300 disabled:cursor-not-allowed text-sm" |
|
> |
|
Rand |
|
</button> |
|
</div> |
|
</details> |
|
|
|
<div class="grid md:grid-cols-2 gap-4 items-start"> |
|
<div> |
|
<div class="relative md:mt-6"> |
|
<div |
|
class="absolute w-full bottom-full flex justify-between items-center" |
|
> |
|
<div class="flex gap-2 w-full"> |
|
<button |
|
id="clear-img-btn" |
|
disabled |
|
title="Clear Image" |
|
class="ml-auto text-xs py-1 bg-white rounded-md disabled:opacity-20 flex gap-1 items-center" |
|
> |
|
<svg |
|
class="" |
|
xmlns="http://www.w3.org/2000/svg" |
|
viewBox="0 0 13 12" |
|
height="1em" |
|
> |
|
<path |
|
d="M1.6.7 12 11.1M12 .7 1.6 11.1" |
|
stroke="#2E3036" |
|
stroke-width="2" |
|
/> |
|
</svg> |
|
</button> |
|
</div> |
|
</div> |
|
<div |
|
id="drop-area" |
|
class="min-h-[250px] flex flex-col items-center justify-center border-2 border-gray-300 border-dashed rounded-xl relative w-full overflow-hidden" |
|
> |
|
<div |
|
class="absolute flex flex-col items-center justify-center space-y-1 text-center" |
|
> |
|
<svg |
|
width="25" |
|
height="25" |
|
viewBox="0 0 25 25" |
|
fill="none" |
|
xmlns="http://www.w3.org/2000/svg" |
|
> |
|
<path |
|
d="M3.5 24.3a3 3 0 0 1-1.9-.8c-.5-.5-.8-1.2-.8-1.9V2.9c0-.7.3-1.3.8-1.9.6-.5 1.2-.7 2-.7h18.6c.7 0 1.3.2 1.9.7.5.6.7 1.2.7 2v18.6c0 .7-.2 1.4-.7 1.9a3 3 0 0 1-2 .8H3.6Zm0-2.7h18.7V2.9H3.5v18.7Zm2.7-2.7h13.3c.3 0 .5 0 .6-.3v-.7l-3.7-5a.6.6 0 0 0-.6-.2c-.2 0-.4 0-.5.3l-3.5 4.6-2.4-3.3a.6.6 0 0 0-.6-.3c-.2 0-.4.1-.5.3l-2.7 3.6c-.1.2-.2.4 0 .7.1.2.3.3.6.3Z" |
|
fill="#000" |
|
/> |
|
</svg> |
|
<div class="flex text-sm text-gray-600"> |
|
<label |
|
for="file-upload" |
|
class="relative cursor-pointer bg-white rounded-md font-medium text-blue-950 hover:text-blue-700" |
|
> |
|
<span>Drag and drop the image here</span> |
|
<span class="block text-xs">or</span> |
|
<span class="block text-xs">Click to upload</span> |
|
</label> |
|
</div> |
|
<input |
|
id="file-upload" |
|
name="file-upload" |
|
type="file" |
|
accept="image/*" |
|
class="sr-only" |
|
/> |
|
</div> |
|
<canvas |
|
id="canvas" |
|
class="z-10 pointer-events-none w-full" |
|
></canvas> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<h3 class="font-medium">Generation:</h3> |
|
<div |
|
class="min-h-[250px] bg-slate-100 text-gray-500 p-4 rounded-md flex flex-col gap-2" |
|
> |
|
<div |
|
id="output-counter" |
|
hidden |
|
class="ml-auto font-semibold grid-rows-1" |
|
></div> |
|
<p hidden id="output-generation" class="grid-rows-2 text-lg"></p> |
|
<span id="output-status" class="m-auto font-light" |
|
>No output yet</span |
|
> |
|
</div> |
|
</div> |
|
</div> |
|
<div> |
|
<div |
|
class="flex gap-3 items-center overflow-x-scroll" |
|
id="image-select" |
|
> |
|
<h3 class="font-medium">Examples:</h3> |
|
|
|
<img |
|
src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/candle/examples/sf.jpg" |
|
class="cursor-pointer w-24 h-24 object-cover" |
|
/> |
|
<img |
|
src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/candle/examples/bike.jpeg" |
|
class="cursor-pointer w-24 h-24 object-cover" |
|
/> |
|
<img |
|
src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/candle/examples/000000000077.jpg" |
|
class="cursor-pointer w-24 h-24 object-cover" |
|
/> |
|
<img |
|
src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/candle/examples/demo-1.jpg" |
|
class="cursor-pointer w-24 h-24 object-cover" |
|
/> |
|
</div> |
|
</div> |
|
</main> |
|
</body> |
|
</html> |
|
|