Add Bootstrap 5 styling to application page

pull/968/head
nearz 2023-05-29 12:14:53 -04:00
parent d7c936b44a
commit e0e00d182c
1 changed files with 210 additions and 147 deletions

View File

@ -6,7 +6,7 @@
<style>
#output {
width: 100%;
height: 100%;
height: 25%;
margin: 0 auto;
margin-top: 10px;
border-left: 0px;
@ -23,151 +23,192 @@
overflow-wrap: normal;
overflow-x: scroll;
}
select {
height: 31px;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="main-container">
<b>Talk - GPT-2 meets Whisper in WebAssembly</b>
<body class="text-bg-dark">
<div id="main-container container px-4 text-center">
<div class="row">
<div class="col"></div>
<div class="col-8">
<h1>Talk - GPT-2 + Whisper in WebAssembly</h1>
<br><br>
<hr>
<h4>Talk with an Artificial Intelligence in your browser. This demo uses:</h4>
<ul>
<li><a href="https://github.com/ggerganov/whisper.cpp">OpenAI's Whisper</a> to listen to you as you speak in the microphone</li>
<li><a href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/talk.wasm">OpenAI's GPT-2</a> to generate text responses</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API">Web Speech API</a> to vocalize the responses through your speakers</li>
</ul>
All of this runs <b class="text-danger">locally in your browser</b> using WebAssembly.
You can find more about this project on <a href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/talk.wasm">GitHub</a>.
<br><br>
<b>More examples:</b>
<a href="https://whisper.ggerganov.com/">main</a> |
<a href="https://whisper.ggerganov.com/bench">bench</a> |
<a href="https://whisper.ggerganov.com/stream">stream</a> |
<a href="https://whisper.ggerganov.com/command">command</a> |
<a href="https://whisper.ggerganov.com/talk">talk</a> |
<br><br>
<hr>
<h5>Select the models you would like to use:</h5>
<div id="model-whisper">
<div class="row">
<div class="col"">
<p class="mb-0">Whisper model:</p>
<button type="button" class="btn btn-secondary btn-sm mt-3" id="fetch-whisper-tiny-en" onclick="loadWhisper('tiny.en')">tiny.en (75 MB)</button>
<button type="button" class="btn btn-secondary btn-sm mt-3 ms-1" id="fetch-whisper-base-en" onclick="loadWhisper('base.en')">base.en (142 MB)</button>
</div>
<div class="col">
<p class="mb-0">Quantized models:</p>
<button type="button" class="btn btn-secondary btn-sm mt-3" id="fetch-whisper-tiny-en-q5_1" onclick="loadWhisper('tiny-en-q5_1')">tiny.en (Q5_1, 31 MB)</button>
<button type="button" class="btn btn-secondary btn-sm mt-3 ms-1" id="fetch-whisper-base-en-q5_1" onclick="loadWhisper('base-en-q5_1')">base.en (Q5_1, 57 MB)</button>
</div>
<div class="col">
<p class="mb-0">GPT-2 model: </p>
<button class="btn btn-secondary btn-sm mt-3" id="fetch-gpt-2-small" onclick="loadGPT2('small')">small 117M (240 MB)</button>
<!--<button id="fetch-gpt-2-medium" onclick="loadGPT2('medium')">medium 345M (720 MB)</button>-->
<!--
<input type="file" id="file" name="file" onchange="loadFile(event, 'gpt-2.bin')" />
-->
</div>
</div>
<div style="display: none;" id="bs-progress-bars" class="row mt-5">
<div class="col-4">
<span id="model-whisper-status" class="mb-2"></span>
<div style="display: none;" id="fetch-whisper-progress-container" class="progress" role="progressbar" aria-label="Warning example" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">
<div id="fetch-whisper-progress" class="progress-bar text-bg-warning" style="width: 0%">0%</div>
</div>
</div>
<div class="col-4">
<span id="model-gpt-2-status" class="mb-2"></span>
<div style="display: none;" id="fetch-gpt-2-container" class="progress" role="progressbar" aria-label="Warning example" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">
<div id="fetch-gpt-2-progress" class="progress-bar text-bg-warning" style="width: 0%">0%</div>
</div>
</div>
</div>
Talk with an Artificial Intelligence in your browser. This demo uses:
<!--
<input type="file" id="file" name="file" onchange="loadFile(event, 'whisper.bin')" />
-->
</div>
<br>
<div id="model-gpt-2">
</div>
<ul>
<li><a href="https://github.com/ggerganov/whisper.cpp">OpenAI's Whisper</a> to listen to you as you speak in the microphone</li>
<li><a href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/talk.wasm">OpenAI's GPT-2</a> to generate text responses</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API">Web Speech API</a> to vocalize the responses through your speakers</li>
</ul>
<hr>
<h5> Click "Start" button to begin the conversation:</h5>
<div id="input">
<button style="margin-right: 10px;" class="btn btn-secondary btn-sm" id="start" onclick="onStart()" disabled>Start</button>
<button style="margin-right: 10px;" class="btn btn-secondary btn-sm" id="stop" onclick="onStop()" disabled>Stop</button>
<button style="margin-right: 10px;" class="btn btn-secondary btn-sm" id="speak0" onclick="onSpeak('Hello')">Say hello</button>
<button style="margin-right: 10px;" class="btn btn-secondary btn-sm" id="speak1" onclick="onSpeakRandom()" disabled>Say something</button>
<button style="margin-right: 10px;" class="btn btn-secondary btn-sm" id="clear" onclick="clearCache()">Clear Cache</button>
</div>
<div>
<select style="margin-top: 10px; margin-right: 10px;" class="btn btn-secondary btn-sm" id="voice" onchange="onVoiceChange()" disabled>
<option value="0">Default</option>
</select>
<select style="margin-top: 10px;" class="btn btn-secondary btn-sm" id="prompt" onchange="onPromptChange()">
<option value="0">Casual</option>
<option value="1">Robot</option>
<option value="2">Scientist</option>
<option value="3">Programmer</option>
<option value="4">Happy</option>
<option value="5">Sad</option>
<option value="6">Philosophical</option>
<option value="7">Angry</option>
<option value="8">Funny</option>
<option value="9">Poetic</option>
<option value="10">Clever</option>
<option value="11">Cute</option>
<option value="12">Smart</option>
<option value="13">Dumb</option>
<option value="14">Boring</option>
<option value="15">Exciting</option>
<option value="16">Interesting</option>
<option value="17">Wiliam Shakespear</option>
<option value="18">J.R.R. Tolkien</option>
<option value="19">George R.R. Martin</option>
<option value="20">Stephen King</option>
</select>
</div>
<br>
<div id="state">
Status: <b><span id="state-status">not started</span></b>
<pre id="state-context">[The text context will be displayed here]</pre>
</div>
<hr>
Debug output:
<textarea class="ps-2" id="output" rows="20"></textarea>
<br>
<b>Troubleshooting</b>
<br><br>
The page does some heavy computations, so make sure:
<ul>
<li>To use a modern web browser (e.g. Chrome, Firefox)</li>
<li>To use a fast desktop or laptop computer (i.e. not a mobile phone)</li>
<li>Your browser supports WASM <a href="https://webassembly.org/roadmap/">Fixed-width SIMD</a></li>
</ul>
Note that these neural network models were not meant to be used in a browser, so the performance and <br>
quality of the results may not be optimal. If you have any questions or suggestions, checkout the following
<a href="https://github.com/ggerganov/whisper.cpp/discussions/167">discussion</a>.
<br><br>
Here is a short video of the demo in action: <a href="https://youtu.be/LeWKl8t1-Hc">https://youtu.be/LeWKl8t1-Hc</a>
<br><br>
All of this runs <b>locally in your browser</b> using WebAssembly.<br>
You can find more about this project on <a href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/talk.wasm">GitHub</a>.
<br><br>
<b>More examples:</b>
<a href="https://whisper.ggerganov.com/">main</a> |
<a href="https://whisper.ggerganov.com/bench">bench</a> |
<a href="https://whisper.ggerganov.com/stream">stream</a> |
<a href="https://whisper.ggerganov.com/command">command</a> |
<a href="https://whisper.ggerganov.com/talk">talk</a> |
<br><br>
<hr>
Select the models you would like to use and click the "Start" button to begin the conversation
<br><br>
<div id="model-whisper">
Whisper model: <span id="model-whisper-status"></span>
<button id="fetch-whisper-tiny-en" onclick="loadWhisper('tiny.en')">tiny.en (75 MB)</button>
<button id="fetch-whisper-base-en" onclick="loadWhisper('base.en')">base.en (142 MB)</button>
<br><br>
Quantized models:<br><br>
<button id="fetch-whisper-tiny-en-q5_1" onclick="loadWhisper('tiny-en-q5_1')">tiny.en (Q5_1, 31 MB)</button>
<button id="fetch-whisper-base-en-q5_1" onclick="loadWhisper('base-en-q5_1')">base.en (Q5_1, 57 MB)</button>
<span id="fetch-whisper-progress"></span>
<!--
<input type="file" id="file" name="file" onchange="loadFile(event, 'whisper.bin')" />
-->
</div>
<br>
<div id="model-gpt-2">
GPT-2 model: <span id="model-gpt-2-status"></span>
<button id="fetch-gpt-2-small" onclick="loadGPT2('small')">small 117M (240 MB)</button>
<!--<button id="fetch-gpt-2-medium" onclick="loadGPT2('medium')">medium 345M (720 MB)</button>-->
<span id="fetch-gpt-2-progress"></span>
<!--
<input type="file" id="file" name="file" onchange="loadFile(event, 'gpt-2.bin')" />
-->
</div>
<br>
<div id="input">
<button id="start" onclick="onStart()" disabled>Start</button>
<button id="stop" onclick="onStop()" disabled>Stop</button>
<select id="voice" onchange="onVoiceChange()" disabled>
<option value="0">Default</option>
</select>
<select id="prompt" onchange="onPromptChange()">
<option value="0">Casual</option>
<option value="1">Robot</option>
<option value="2">Scientist</option>
<option value="3">Programmer</option>
<option value="4">Happy</option>
<option value="5">Sad</option>
<option value="6">Philosophical</option>
<option value="7">Angry</option>
<option value="8">Funny</option>
<option value="9">Poetic</option>
<option value="10">Clever</option>
<option value="11">Cute</option>
<option value="12">Smart</option>
<option value="13">Dumb</option>
<option value="14">Boring</option>
<option value="15">Exciting</option>
<option value="16">Interesting</option>
<option value="17">Wiliam Shakespear</option>
<option value="18">J.R.R. Tolkien</option>
<option value="19">George R.R. Martin</option>
<option value="20">Stephen King</option>
</select>
<button id="speak0" onclick="onSpeak('Hello')">Say hello</button>
<button id="speak1" onclick="onSpeakRandom()" disabled>Say something</button>
<button id="clear" onclick="clearCache()">Clear Cache</button>
</div>
<br>
<div id="state">
Status: <b><span id="state-status">not started</span></b>
<pre id="state-context">[The text context will be displayed here]</pre>
</div>
<hr>
Debug output:
<textarea id="output" rows="20"></textarea>
<br>
<b>Troubleshooting</b>
<br><br>
The page does some heavy computations, so make sure:
<ul>
<li>To use a modern web browser (e.g. Chrome, Firefox)</li>
<li>To use a fast desktop or laptop computer (i.e. not a mobile phone)</li>
<li>Your browser supports WASM <a href="https://webassembly.org/roadmap/">Fixed-width SIMD</a></li>
</ul>
Note that these neural network models were not meant to be used in a browser, so the performance and <br>
quality of the results may not be optimal. If you have any questions or suggestions, checkout the following
<a href="https://github.com/ggerganov/whisper.cpp/discussions/167">discussion</a>.
<br><br>
Here is a short video of the demo in action: <a href="https://youtu.be/LeWKl8t1-Hc">https://youtu.be/LeWKl8t1-Hc</a>
<br><br>
<div class="cell-version">
<span>
|
Build time: <span class="nav-link">@GIT_DATE@</span> |
Commit hash: <a class="nav-link" href="https://github.com/ggerganov/whisper.cpp/commit/@GIT_SHA1@">@GIT_SHA1@</a> |
Commit subject: <span class="nav-link">@GIT_COMMIT_SUBJECT@</span> |
<a class="nav-link" href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/talk.wasm">Source Code</a> |
</span>
<div class="row my-3 pb-4">
<div class="col"></div>
<div class="col-6">
<p class="d-inline">
Build time: <span class="d-inline nav-link">@GIT_DATE@</span> |
</p>
<p class="d-inline">
Commit hash: <a class="d-inline nav-link" href="https://github.com/ggerganov/whisper.cpp/commit/@GIT_SHA1@">@GIT_SHA1@</a> |
</p>
<p class="d-inline">
Commit subject: <span class="d-inline nav-link">@GIT_COMMIT_SUBJECT@</span> |
</p>
<p class="d-inline">
<a class="d-inline nav-link" href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/talk.wasm">Source Code</a> |
</p>
</div>
<div class="col"></div>
</div>
</div>
<div class="col"></div>
</div>
</div>
@ -291,24 +332,40 @@
'tiny-en-q5_1': 31,
'base-en-q5_1': 57,
};
let ids = {
'tiny.en': 'fetch-whisper-tiny-en',
'base.en': 'fetch-whisper-base-en',
'tiny-en-q5_1': 'fetch-whisper-tiny-en-q5_1',
'base-en-q5_1': 'fetch-whisper-base-en-q5_1',
};
let url = urls[model];
let dst = 'whisper.bin';
let size_mb = sizes[model];
let id = ids[model];
model_whisper = model;
document.getElementById('fetch-whisper-tiny-en').style.display = 'none';
document.getElementById('fetch-whisper-base-en').style.display = 'none';
document.getElementById(id).classList.replace("btn-secondary", "btn-primary");
document.getElementById("bs-progress-bars").style.display = '';
document.getElementById("fetch-whisper-progress-container").style.display = '';
document.getElementById('fetch-whisper-tiny-en-q5_1').style.display = 'none';
document.getElementById('fetch-whisper-base-en-q5_1').style.display = 'none';
document.getElementById('fetch-whisper-tiny-en').disabled = true;
document.getElementById('fetch-whisper-base-en').disabled = true;
document.getElementById('model-whisper-status').innerHTML = 'loading "' + model + '" ... ';
document.getElementById('fetch-whisper-tiny-en-q5_1').disabled = true;
document.getElementById('fetch-whisper-base-en-q5_1').disabled = true;
document.getElementById('model-whisper-status').textContent = "Load " + model + ":";
cbProgress = function(p) {
let el = document.getElementById('fetch-whisper-progress');
el.innerHTML = Math.round(100*p) + '%';
el.style.width = Math.round(100*p) + '%';
if(p == 1){
el.classList.replace("text-bg-warning", "text-bg-danger");
}
};
cbCancel = function() {
@ -342,12 +399,18 @@
model_gpt_2 = model;
document.getElementById('fetch-gpt-2-small').style.display = 'none';
document.getElementById('model-gpt-2-status').innerHTML = 'loading "' + model + '" ... ';
document.getElementById('fetch-gpt-2-small').classList.replace("btn-secondary", "btn-primary");
document.getElementById('fetch-gpt-2-small').disabled = true;
document.getElementById('fetch-gpt-2-container').style.display = '';
document.getElementById('model-gpt-2-status').innerHTML = "Load " + model + ":";
cbProgress = function(p) {
let el = document.getElementById('fetch-gpt-2-progress');
el.innerHTML = Math.round(100*p) + '%';
el.style.width = Math.round(100*p) + '%';
if(p == 1){
el.classList.replace("text-bg-warning", "text-bg-danger");
}
};
cbCancel = function() {