| <!DOCTYPE html> |
| <html lang="en"> |
|
|
| <head> |
| <meta charset="UTF-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>🪞Mirror</title> |
| <link rel="stylesheet" href="https://unpkg.com/boltcss/bolt.min.css"> |
| <script type="importmap"> |
| { |
| "imports": { |
| "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" |
| } |
| } |
| </script> |
| <style> |
| body { |
| max-width: 800px; |
| margin: 40px auto; |
| padding: 0 20px; |
| } |
| |
| .form-group { |
| display: flex; |
| flex-direction: row; |
| justify-content: flex-start; |
| align-items: center; |
| } |
| |
| label { |
| margin-right: 1rem; |
| } |
| |
| button { |
| margin: 0.2rem 0.2rem; |
| } |
| |
| button:hover { |
| background-color: #dbdbdb; |
| } |
| |
| footer { |
| text-align: center; |
| margin-top: 2rem; |
| } |
| |
| input { |
| width: 100%; |
| } |
| |
| .button-group { |
| margin-top: 1rem; |
| margin-bottom: 1rem; |
| } |
| |
| .submit-button { |
| background-color: #ffc83d; |
| color: #d67d00; |
| font-weight: bold; |
| } |
| |
| .lc-button { |
| background-color: #c4e5be; |
| } |
| |
| .lm-button { |
| background-color: #dae7fb; |
| } |
| |
| .lr-button { |
| background-color: #fff3ce; |
| } |
| |
| .submit-button:hover { |
| background-color: #ffc83dc0; |
| } |
| |
| .download-button { |
| background-color: #98ca56; |
| color: white; |
| font-weight: bold; |
| } |
| |
| .download-button:hover { |
| background-color: #98ca56d1; |
| } |
| |
| .output-title { |
| margin-top: 2rem; |
| margin-bottom: 0; |
| display: block; |
| background-color: #98ca56; |
| color: white; |
| font-weight: bold; |
| font-size: large; |
| padding: 6px 15px; |
| border-top-left-radius: 6px; |
| border-top-right-radius: 6px; |
| } |
| |
| .output-box { |
| margin-top: 0; |
| padding: 6px 15px; |
| background-color: white; |
| border: 2px solid #98ca56; |
| border-bottom-left-radius: 6px; |
| border-bottom-right-radius: 6px; |
| } |
| </style> |
| </head> |
|
|
| <body> |
| <header> |
| <h1>🪞Mirror</h1> |
| <p> |
| 🪞Mirror can help you deal with a wide range of Natural Language Understanding and Information Extraction tasks. |
| </p> |
| <p>🔍 Mechanism behind this demo: <a href="https://arxiv.org/abs/2311.05419" target="_blank">Mirror paper</a>.</p> |
| <p> |
| 🌟 Star me on <a href="https://github.com/Spico197/Mirror" target="_blank">GitHub</a>! |
| </p> |
| <p>📢 This demo only supports English tasks. For Chinese Information Extraction tasks, please refer to this model: <a href="https://huggingface.co/Spico/mirror-chinese-mrcqa-alpha" target="_blank">Spico/mirror-chinese-mrcqa-alpha</a>.</p> |
| </header> |
|
|
| <main> |
| <div id="app"> |
| <div> |
| <label for="example-select"><strong>Examples</strong></label> |
| <select id="example-select" v-model="selectedExample"> |
| <optgroup label="Named Entity Recognition"> |
| <option>Person & Nationality</option> |
| </optgroup> |
| <optgroup label="Relation Extraction"> |
| <option>Break up</option> |
| </optgroup> |
| <optgroup label="Classification"> |
| <option>The most handsome man</option> |
| <option>I'm more handsome!</option> |
| </optgroup> |
| <optgroup label="Machine Reading Comprehension"> |
| <option>The former CEO of Apple</option> |
| <option>The new CEO of Apple</option> |
| </optgroup> |
| </select> |
| </div> |
| <div> |
| <label for="instruction"><strong>Instruction</strong></label> |
| <input id="instruction" type="text" v-model="instruction" placeholder="Mirror mirror tell me ..." size="200"> |
| </div> |
| <div> |
| <label for="schema"><strong>Schema Labels</strong></label> |
| <p>For entities, relations or classification, input <code>{"ent|rel|cls": ["type1", "type2"]}</code> .</p> |
| <input id="schema" type="text" v-model="schema" size="200"> |
| </div> |
| <div> |
| <label for="text"><strong>Text</strong></label> |
| <input id="text" type="text" v-model="text" size="200"> |
| </div> |
| |
| |
| |
| |
|
|
| <div class="button-group"> |
| <button @click.prevent="reset">Reset</button> |
| <button @click.prevent="clearOutput">Clear Output</button> |
| <button class="submit-button" @click.prevent="getResults">Ask Mirror</button> |
| </div> |
|
|
| <div v-if="timerHandler"> |
| <p>⏱️ {{ searchSecondsString }}</p> |
| </div> |
|
|
| <div> |
| <div v-if="isNotEmptyObj(results)"> |
| <label for="output"><strong>Output</strong></label> |
| <table> |
| <thead> |
| <th>Item</th> |
| <th>Predicted</th> |
| </thead> |
| <tbody> |
| <tr v-for="(value, key, index) in results" :key="index"> |
| <template v-if="value.length"> |
| <td>{{ key }}</td> |
| <td>{{ value }}</td> |
| </template> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| </div> |
|
|
| </div> |
| </main> |
|
|
| <footer> |
| <hr> |
| Made by Mirror Team w/ 💖 |
| </footer> |
|
|
| <script type="module"> |
| import { createApp, ref, computed, toRaw, watch } from 'vue' |
| |
| createApp( |
| { |
| setup() { |
| const instruction = ref("") |
| const text = ref("") |
| const background = ref("") |
| const selectedExample = ref("") |
| const schema = ref("{}") |
| const results = ref({}) |
| const timerHandler = ref(0) |
| const searchSeconds = ref(0.0) |
| const searchSecondsString = computed(() => { |
| return `${searchSeconds.value.toFixed(1)}s` |
| }) |
| |
| function isNotEmptyObj(obj) { |
| return Object.keys(obj).length > 0 |
| } |
| |
| function clearOutput() { |
| timerHandler.value = 0 |
| results.value = {} |
| } |
| |
| function reset() { |
| schema.value = "{}" |
| instruction.value = "" |
| text.value = "" |
| clearOutput() |
| } |
| |
| function startTimer() { |
| searchSeconds.value = 0.0 |
| timerHandler.value = setInterval(() => { |
| searchSeconds.value += 0.1 |
| }, 100) |
| } |
| |
| function endTimer() { |
| if (timerHandler.value > 0) { |
| clearInterval(timerHandler.value) |
| } |
| } |
| |
| function getResults() { |
| clearOutput() |
| startTimer() |
| const data = { |
| "id": Date.now().toString(), |
| "instruction": instruction.value, |
| "schema": JSON.parse(schema.value), |
| "text": text.value, |
| "background": background.value, |
| "ans": {}, |
| } |
| const postData = JSON.stringify({ |
| "data": [data], |
| }) |
| fetch( |
| "/process", |
| { |
| method: "POST", |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: postData, |
| } |
| ) |
| .then((response) => response.json()) |
| .then((json) => { |
| if (json["ok"] === false) { |
| alert(json["msg"]) |
| } else { |
| results.value = json["results"][0]["results"] |
| } |
| }) |
| .catch((err) => { alert(err) }) |
| .finally(() => endTimer()) |
| } |
| |
| watch( |
| () => selectedExample.value, |
| (newValue, oldValue) => { |
| if (newValue !== oldValue) { |
| reset() |
| console.log(newValue) |
| if (newValue === "Person & Nationality") { |
| instruction.value = "Please identify any entities in the provided text and classify them based on their types." |
| text.value = "Isaac Newton was an English mathematician." |
| schema.value = '{"ent": ["person", "nationality"]}' |
| } else if (newValue === "Break up") { |
| instruction.value = "Please extract the entity relationship triplet." |
| text.value = "The drama surrounding the high-profile divorce between Hollywood actors Johnny Depp and Amber Heard appears to be over as the couple reportedly reached an amicable settlement." |
| schema.value = '{"rel": ["break up"]}' |
| } else if (newValue === "The most handsome man") { |
| instruction.value = "Mirror Mirror tell me, who's the most handsome man in the world?" |
| text.value = "" |
| schema.value = '{"cls": ["Tong Zhu", "Leonardo Dicaprio"]}' |
| } else if (newValue === "I'm more handsome!") { |
| instruction.value = "Mirror Mirror tell me, who's the most handsome man in the world?" |
| text.value = "Tong Zhu won the Most Handsome Man Award every year for ten consecutive years." |
| schema.value = '{"cls": ["Tong Zhu", "Leonardo Dicaprio"]}' |
| } else if (newValue === "The former CEO of Apple") { |
| instruction.value = "Who's the former CEO of Apple?" |
| text.value = "After Jobs resigned as CEO and became chairman of the board, Cook was named the new chief executive officer of Apple Inc. on August 24, 2011." |
| schema.value = '{}' |
| } else if (newValue === "The new CEO of Apple") { |
| instruction.value = "Who's the new CEO of Apple?" |
| text.value = "After Jobs resigned as CEO and became chairman of the board, Cook was named the new chief executive officer of Apple Inc. on August 24, 2011." |
| schema.value = '{}' |
| } |
| } |
| } |
| ) |
| |
| return { |
| instruction, |
| text, |
| background, |
| schema, |
| results, |
| reset, |
| clearOutput, |
| getResults, |
| searchSecondsString, |
| timerHandler, |
| isNotEmptyObj, |
| selectedExample, |
| } |
| } |
| } |
| ).mount("#app") |
| </script> |
| </body> |
|
|
| </html> |