| <!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Qwen 3.5 — In-Browser Vision Chat</title> |
| <link rel="preconnect" href="https://fonts.googleapis.com" /> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> |
| <link |
| href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@300;400;500&family=Instrument+Serif:ital@0;1&family=Manrope:wght@300;400;500;600;700&display=swap" |
| rel="stylesheet" |
| /> |
| <link |
| rel="icon" |
| href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚡️</text></svg>" |
| /> |
| <link rel="stylesheet" href="index.css" /> |
| </head> |
| <body> |
| <div id="landing" class="screen active"> |
| <div class="landing-glow"></div> |
| <div class="landing-tag">Multimodal AI · 100% Local</div> |
| <h1 class="landing-title">Qwen 3.5 <em>Vision</em></h1> |
| <p class="landing-sub"> |
| Run a multimodal vision-language model entirely in your browser. No |
| server, no API keys — powered by Transformers.js and WebGPU. |
| </p> |
| <div class="landing-specs"> |
| <div class="spec"> |
| <div class="spec-value">Vision + Language</div> |
| <div class="spec-label">Unified Multimodal</div> |
| </div> |
| <div class="spec"> |
| <div class="spec-value">201 Languages</div> |
| <div class="spec-label">Global Coverage</div> |
| </div> |
| <div class="spec"> |
| <div class="spec-value">Reasoning</div> |
| <div class="spec-label">Code · Agents · Visual</div> |
| </div> |
| </div> |
| <div class="btn-load-group"> |
| <button class="btn-load" id="btnLoad"> |
| Load Model (<span id="modelSizeLabel">0.8B</span>) |
| </button> |
| <button |
| class="btn-load-arrow" |
| id="btnModelArrow" |
| title="Choose model size" |
| > |
| ▾ |
| </button> |
| <select class="model-select" id="modelSelect"> |
| <option value="onnx-community/Qwen3.5-0.8B-ONNX-OPT">0.8B</option> |
| <option value="onnx-community/Qwen3.5-2B-ONNX-OPT">2B</option> |
| <option value="onnx-community/Qwen3.5-4B-ONNX-OPT">4B</option> |
| </select> |
| </div> |
| <div class="landing-footer"> |
| Built with |
| <a href="https://huggingface.co/docs/transformers.js" target="_blank" |
| >Transformers.js</a |
| > |
| </div> |
| </div> |
|
|
| <div id="loading" class="screen"> |
| <div class="loader-ring"></div> |
| <div> |
| <div class="loader-text" id="loaderText">Initializing model…</div> |
| <div class="loader-sub"> |
| Model weights are cached for future visits. |
| </div> |
| </div> |
| </div> |
|
|
| <div id="chat" class="screen"> |
| <div class="chat-header"> |
| <div class="chat-header-left"> |
| <div class="chat-avatar">Q</div> |
| <div> |
| <div class="chat-header-title">Qwen 3.5 Vision</div> |
| <div class="chat-header-status">Ready on WebGPU</div> |
| </div> |
| </div> |
| <div class="chat-header-controls"> |
| <label |
| class="toggle-reasoning" |
| title="Let the model think step-by-step before answering" |
| > |
| <input type="checkbox" id="reasoningToggle" /> |
| <span class="toggle-slider"></span> |
| <span class="toggle-label">Reasoning</span> |
| </label> |
| <button class="btn-reset" id="btnReset">Reset Chat</button> |
| </div> |
| </div> |
|
|
| <div class="error-banner" id="errorBanner"></div> |
|
|
| <div class="chat-messages" id="chatMessages"> |
| <div class="welcome-msg"> |
| <h3>Start a conversation</h3> |
| <p> |
| Optionally attach an image, then type your message.<br />The model |
| runs entirely in your browser. |
| </p> |
| </div> |
| </div> |
|
|
| <div class="chat-input-area"> |
| <div class="image-preview-bar" id="imagePreview"> |
| <img class="image-preview-thumb" id="imageThumb" src="" alt="" /> |
| <span class="image-preview-name" id="imageName"></span> |
| <button class="btn-remove-image" id="btnRemoveImage">×</button> |
| </div> |
| <div class="chat-input-row"> |
| <button class="btn-attach" id="btnAttach" title="Attach image"> |
| <svg |
| width="18" |
| height="18" |
| viewBox="0 0 24 24" |
| fill="none" |
| stroke="currentColor" |
| stroke-width="2" |
| stroke-linecap="round" |
| stroke-linejoin="round" |
| > |
| <rect x="3" y="3" width="18" height="18" rx="2" /> |
| <circle cx="8.5" cy="8.5" r="1.5" /> |
| <polyline points="21 15 16 10 5 21" /> |
| </svg> |
| </button> |
| <input |
| type="file" |
| id="fileInput" |
| accept="image/png,image/jpeg,image/webp,image/gif,image/bmp" |
| hidden |
| /> |
| <div class="input-wrap"> |
| <textarea |
| id="msgInput" |
| rows="1" |
| placeholder="Describe this image…" |
| ></textarea> |
| </div> |
| <button class="btn-send" id="btnSend" disabled title="Send"> |
| <svg |
| class="icon-send" |
| width="18" |
| height="18" |
| viewBox="0 0 24 24" |
| fill="none" |
| stroke="currentColor" |
| stroke-width="2.5" |
| stroke-linecap="round" |
| stroke-linejoin="round" |
| > |
| <line x1="22" y1="2" x2="11" y2="13" /> |
| <polygon points="22 2 15 22 11 13 2 9 22 2" /> |
| </svg> |
| <svg |
| class="icon-stop" |
| width="16" |
| height="16" |
| viewBox="0 0 24 24" |
| fill="currentColor" |
| > |
| <rect x="4" y="4" width="16" height="16" rx="2" /> |
| </svg> |
| </button> |
| </div> |
| <div class="chat-footer-note"> |
| No chats are sent to a server. Everything runs locally in your |
| browser. AI can make mistakes. Check important info. |
| </div> |
| </div> |
| </div> |
|
|
| <script src="index.js" type="module"></script> |
| </body> |
| </html> |
|
|