-
Notifications
You must be signed in to change notification settings - Fork 580
Improved error handling, and notices about device limitations + HTTPS warning #258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,11 +26,20 @@ function createEmojiButton(result) { | |||||||||||||||||
| // Check for WebGPU availability and displays an error message if it's not available | ||||||||||||||||||
| function checkWebGPU() { | ||||||||||||||||||
| if (!navigator.gpu) { | ||||||||||||||||||
| statusMessageContainer.innerHTML = ` | ||||||||||||||||||
| let message = ` | ||||||||||||||||||
| This application requires WebGPU to run the model in your browser. | ||||||||||||||||||
| Please update your browser to enable WebGPU support, try a different browser (like Chrome or Edge, version 113+), or ensure your GPU drivers are up to date.</br></br> | ||||||||||||||||||
| For more details, read the <a href="https://github.com/gpuweb/gpuweb/wiki/Implementation-Status" target="_blank" style="f; color: #286aac">WebGPU Implementation Status</a>. | ||||||||||||||||||
| For more details, read the <a href="https://github.com/gpuweb/gpuweb/wiki/Implementation-Status" target="_blank" style="color: #286aac">WebGPU Implementation Status</a>. | ||||||||||||||||||
| `; | ||||||||||||||||||
|
|
||||||||||||||||||
| if (!window.isSecureContext) { | ||||||||||||||||||
| message += ` | ||||||||||||||||||
| <br/><br/> | ||||||||||||||||||
| <strong>Note:</strong> WebGPU requires a secure context. Please access this page over HTTPS or from 'localhost'. Accessing a local server via its IP address also requires an HTTPS setup in many instances (e.g. iOS26 Safari). | ||||||||||||||||||
| `; | ||||||||||||||||||
|
Comment on lines
+36
to
+39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There appears to be a typo "iOS26" in the note. It's better to either correct it to a specific version or make it more general, like 'iOS Safari', to avoid it becoming outdated.
Suggested change
|
||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| statusMessageContainer.innerHTML = message; | ||||||||||||||||||
| generateBtn.disabled = true; | ||||||||||||||||||
| return false; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
@@ -40,7 +49,7 @@ function checkWebGPU() { | |||||||||||||||||
| // Main function to run worker | ||||||||||||||||||
| async function initializeModelInWorker() { | ||||||||||||||||||
| console.log("[UI] Initializing application..."); | ||||||||||||||||||
|
|
||||||||||||||||||
| // Create a simulated progress loader that clears once the model loads | ||||||||||||||||||
| if (!checkWebGPU()) { | ||||||||||||||||||
| return; | ||||||||||||||||||
|
|
@@ -70,18 +79,18 @@ async function initializeModelInWorker() { | |||||||||||||||||
| statusMessageContainer.textContent = `Loading model (100%)`; // Show 100% briefly | ||||||||||||||||||
| modelReady = true; | ||||||||||||||||||
| generateBtn.disabled = false; // Enable the generation button upon model load | ||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||
| setTimeout(() => { | ||||||||||||||||||
| statusMessageContainer.innerHTML = ``; // Then empty status message | ||||||||||||||||||
| }, 500); | ||||||||||||||||||
| break; | ||||||||||||||||||
|
|
||||||||||||||||||
| case "result": | ||||||||||||||||||
| const line = data.trim(); | ||||||||||||||||||
| if (line) { | ||||||||||||||||||
| createEmojiButton(line); | ||||||||||||||||||
| } | ||||||||||||||||||
| break; | ||||||||||||||||||
|
|
||||||||||||||||||
| case "complete": | ||||||||||||||||||
| responseComplete(); | ||||||||||||||||||
| break; | ||||||||||||||||||
|
|
@@ -110,7 +119,7 @@ async function initializeModelInWorker() { | |||||||||||||||||
| function responseComplete() { | ||||||||||||||||||
| generateBtn.classList.remove('generating'); | ||||||||||||||||||
| generateBtn.disabled = false; | ||||||||||||||||||
|
|
||||||||||||||||||
| if (responseOutput.childElementCount === 0) { | ||||||||||||||||||
| statusMessageContainer.textContent = "No results"; | ||||||||||||||||||
| } else { | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,14 +7,29 @@ This app demonstrates how to generate emojis from a text input using a fine-tune | |||||||||||||
| 2. In the worker.js file, update the model string in the `pipeline()` function call to the model on Hugging Face Hub. | ||||||||||||||
| 1. Alternatively, download and place the model files in a new subdirectory i.e. `app-transformersjs/myemoji-gemma-3-270m-it-onnx/` for full offline use. | ||||||||||||||
| 3. Open terminal on your computer and navigate (`cd`) to the app folder. | ||||||||||||||
| 4. Run `npx serve` to start the local server. | ||||||||||||||
| 5. Open the provided `localhost` address in your browser to run the app. | ||||||||||||||
| 4. To run the app, you need a local web server. For development and testing, it is recommended to use a secure (HTTPS) server, as WebGPU may not be available in non-secure contexts. | ||||||||||||||
| 1. **For a secure server:** | ||||||||||||||
| 1. If you don't have a local certificate, create one by running this command in your terminal at the root of this project (/app-transformersjs): | ||||||||||||||
| ```bash | ||||||||||||||
| openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj "/C=US/ST=CA/L=Mountain View/O=Dev/CN=localhost" | ||||||||||||||
| ``` | ||||||||||||||
|
Comment on lines
+13
to
+15
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||
| 2. Start the server with the following command: | ||||||||||||||
| ```bash | ||||||||||||||
| npx http-server -S -c-1 -p 8080 | ||||||||||||||
| ``` | ||||||||||||||
| 2. **For a non-secure server:** | ||||||||||||||
| ```bash | ||||||||||||||
| npx serve | ||||||||||||||
| ``` | ||||||||||||||
| 5. Open the provided `localhost` address in your browser to run the app (you may have to accept untrusted SSL warning in your browser). | ||||||||||||||
|
|
||||||||||||||
| **Requirements:** Browser with [WebGPU support](https://caniuse.com/webgpu) | ||||||||||||||
| **Requirements:** Browser with [WebGPU support](https://caniuse.com/webgpu). Note that some platforms, like iOS Safari, require a secure context (HTTPS) to enable WebGPU. | ||||||||||||||
|
|
||||||||||||||
| ## How it works | ||||||||||||||
| This demo sets up a simple web server to host a frontend where users can enter a text prompt. This starts a generation process in a web worker to avoid blocking the main UI thread. The worker uses [Transformers.js](https://huggingface.co/docs/transformers.js/index) to generate a response from the model and send it back to the user. | ||||||||||||||
|
|
||||||||||||||
| **Device Limitations:** Running language models in the browser is memory-intensive. While this demo may work on high-end desktop machines, some memory-constrained devices, especially on iOS, may fail to load the model and cause the page to crash. This is due to strict memory limits imposed by the operating system on browser tabs. Even when running with 16-bit float precision, the Gemma 270M model can exceed these limits. | ||||||||||||||
|
|
||||||||||||||
| ## Resources | ||||||||||||||
| * [Notebook: Fine-tune Gemma 3 270M](https://github.com/google-gemini/gemma-cookbook/blob/main/Demos/Emoji-Gemma-on-Web/resources/Fine_tune_Gemma_3_270M_for_emoji_generation.ipynb) | ||||||||||||||
| * [Notebook: Convert Gemma 3 270M to ONNX](https://github.com/google-gemini/gemma-cookbook/blob/main/Demos/Emoji-Gemma-on-Web/resources/Convert_Gemma_3_270M_to_ONNX.ipynb) | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
opensslcommand includes a very specific subject. While this works, a simpler subject focusing only on the Common Name (CN) is sufficient for a local development certificate and is less confusing for users who might think they need to change these values.