AnthoneoJ commited on
Commit
1fcfb9b
·
1 Parent(s): 2a62878

Delete app

Browse files
app/.eslintrc.cjs DELETED
@@ -1,20 +0,0 @@
1
- module.exports = {
2
- root: true,
3
- env: { browser: true, es2020: true },
4
- extends: [
5
- 'eslint:recommended',
6
- 'plugin:react/recommended',
7
- 'plugin:react/jsx-runtime',
8
- 'plugin:react-hooks/recommended',
9
- ],
10
- ignorePatterns: ['dist', '.eslintrc.cjs'],
11
- parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12
- settings: { react: { version: '18.2' } },
13
- plugins: ['react-refresh'],
14
- rules: {
15
- 'react-refresh/only-export-components': [
16
- 'warn',
17
- { allowConstantExport: true },
18
- ],
19
- },
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/.gitignore DELETED
@@ -1,24 +0,0 @@
1
- # Logs
2
- logs
3
- *.log
4
- npm-debug.log*
5
- yarn-debug.log*
6
- yarn-error.log*
7
- pnpm-debug.log*
8
- lerna-debug.log*
9
-
10
- node_modules
11
- dist
12
- dist-ssr
13
- *.local
14
-
15
- # Editor directories and files
16
- .vscode/*
17
- !.vscode/extensions.json
18
- .idea
19
- .DS_Store
20
- *.suo
21
- *.ntvs*
22
- *.njsproj
23
- *.sln
24
- *.sw?
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/index.html DELETED
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Semantic Similarity - Vite + React</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script type="module" src="/src/main.jsx"></script>
12
- </body>
13
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/package-lock.json DELETED
The diff for this file is too large to render. See raw diff
 
app/package.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "name": "react-semantic-similarity",
3
- "private": true,
4
- "version": "0.0.0",
5
- "type": "module",
6
- "scripts": {
7
- "dev": "vite",
8
- "build": "vite build",
9
- "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10
- "preview": "vite preview"
11
- },
12
- "dependencies": {
13
- "@xenova/transformers": "^2.5.0",
14
- "react": "^18.2.0",
15
- "react-dom": "^18.2.0"
16
- },
17
- "devDependencies": {
18
- "@types/react": "^18.2.15",
19
- "@types/react-dom": "^18.2.7",
20
- "@vitejs/plugin-react": "^4.0.3",
21
- "eslint": "^8.45.0",
22
- "eslint-plugin-react": "^7.32.2",
23
- "eslint-plugin-react-hooks": "^4.6.0",
24
- "eslint-plugin-react-refresh": "^0.4.3",
25
- "vite": "^4.4.5"
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/public/vite.svg DELETED
app/src/App.css DELETED
@@ -1,108 +0,0 @@
1
- #root {
2
- max-width: 1280px;
3
- margin: 0 auto;
4
- padding: 2rem;
5
- text-align: center;
6
- }
7
-
8
- .textbox-container {
9
- display: flex;
10
- justify-content: center;
11
- gap: 20px;
12
- width: 800px;
13
- }
14
-
15
- .textbox-container>textarea, .textbox-container>.candidates-container {
16
- width: 50%;
17
- }
18
-
19
- .candidate-line-container {
20
- display: flex;
21
- flex-direction: column;
22
- }
23
-
24
- .output-score {
25
- font-size: 1.0em;
26
- font-style: italic;
27
- }
28
-
29
- .progress-container {
30
- position: relative;
31
- font-size: 14px;
32
- color: white;
33
- background-color: #e9ecef;
34
- border: solid 1px;
35
- border-radius: 8px;
36
- text-align: left;
37
- overflow: hidden;
38
- }
39
-
40
- .progress-bar {
41
- padding: 0 4px;
42
- z-index: 0;
43
- top: 0;
44
- width: 1%;
45
- height: 100%;
46
- overflow: hidden;
47
- background-color: #007bff;
48
- white-space: nowrap;
49
- }
50
-
51
- .progress-text {
52
- z-index: 2;
53
- }
54
-
55
- .selector-container {
56
- display: flex;
57
- gap: 20px;
58
- }
59
-
60
- .progress-bars-container {
61
- padding: 8px;
62
- height: 140px;
63
- }
64
-
65
- .container {
66
- margin: 25px;
67
- display: flex;
68
- flex-direction: column;
69
- gap: 10px;
70
- }
71
-
72
-
73
-
74
- .logo {
75
- height: 6em;
76
- padding: 1.5em;
77
- will-change: filter;
78
- transition: filter 300ms;
79
- }
80
- .logo:hover {
81
- filter: drop-shadow(0 0 2em #646cffaa);
82
- }
83
- .logo.react:hover {
84
- filter: drop-shadow(0 0 2em #61dafbaa);
85
- }
86
-
87
- @keyframes logo-spin {
88
- from {
89
- transform: rotate(0deg);
90
- }
91
- to {
92
- transform: rotate(360deg);
93
- }
94
- }
95
-
96
- @media (prefers-reduced-motion: no-preference) {
97
- a:nth-of-type(2) .logo {
98
- animation: logo-spin infinite 20s linear;
99
- }
100
- }
101
-
102
- .card {
103
- padding: 2em;
104
- }
105
-
106
- .read-the-docs {
107
- color: #888;
108
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/src/App.jsx DELETED
@@ -1,150 +0,0 @@
1
- // Remember to import the relevant hooks
2
- import { useEffect, useRef, useState } from 'react'
3
- import Progress from './components/Progress';
4
-
5
- import './App.css'
6
-
7
- function App() {
8
- // Model loading
9
- const [ready, setReady] = useState(null);
10
- const [disabled, setDisabled] = useState(false);
11
- const [progressItems, setProgressItems] = useState([]);
12
-
13
- // Reference and candidate sentences
14
- const [referenceSentence, setReferenceSentence] = useState('Dumbledore lost the fight against Voldemort.');
15
- const [candidateSentence1, setCandidateSentence1] = useState('I\'m sad that Voldemort won the battle.');
16
- const [candidateSentence2, setCandidateSentence2] = useState('The evil prevailed.');
17
- const [candidateSentence3, setCandidateSentence3] = useState('The good prevailed.');
18
-
19
- // Similarity output
20
- const [output_1, setOutput1] = useState('');
21
- const [output_2, setOutput2] = useState('');
22
- const [output_3, setOutput3] = useState('');
23
-
24
- // Create a reference to the worker object.
25
- const worker = useRef(null);
26
-
27
- // We use the `useEffect` hook to setup the worker as soon as the `App` component is mounted.
28
- useEffect(() => {
29
- if (!worker.current) {
30
- // Create the worker if it does not yet exist.
31
- worker.current = new Worker(new URL('./worker.js', import.meta.url), {
32
- type: 'module'
33
- });
34
- }
35
-
36
- // Create a callback function for messages from the worker thread.
37
- const onMessageReceived = (e) => {
38
- switch (e.data.status) {
39
- case 'initiate':
40
- // Model file start load: add a new progress item to the list.
41
- setReady(false);
42
- setProgressItems(prev => [...prev, e.data]);
43
- break;
44
-
45
- case 'progress':
46
- // Model file progress: update one of the progress items.
47
- setProgressItems(
48
- prev => prev.map(item => {
49
- if (item.file === e.data.file) {
50
- return { ...item, progress: e.data.progress }
51
- }
52
- return item;
53
- })
54
- );
55
- break;
56
-
57
- case 'done':
58
- // Model file loaded: remove the progress item from the list.
59
- setProgressItems(
60
- prev => prev.filter(item => item.file !== e.data.file)
61
- );
62
- break;
63
-
64
- case 'ready':
65
- // Pipeline ready: the worker is ready to accept messages.
66
- setReady(true);
67
- break;
68
-
69
- case 'update_1':
70
- // Generation update: update the output text.
71
- setOutput1(e.data.output);
72
- break;
73
-
74
- case 'update_2':
75
- // Generation update: update the output text.
76
- setOutput2(e.data.output);
77
- break;
78
-
79
- case 'update_3':
80
- // Generation update: update the output text.
81
- setOutput3(e.data.output);
82
- break;
83
-
84
- case 'complete':
85
- // Generation complete: re-enable the "Compute" button
86
- setDisabled(false);
87
- break;
88
- }
89
- };
90
-
91
- // Attach the callback function as an event listener.
92
- worker.current.addEventListener('message', onMessageReceived);
93
-
94
- // Define a cleanup function for when the component is unmounted.
95
- return () => worker.current.removeEventListener('message', onMessageReceived);
96
- });
97
-
98
- const compute = () => {
99
- setDisabled(true);
100
- worker.current.postMessage({
101
- refsent: referenceSentence,
102
- cand1: candidateSentence1,
103
- cand2: candidateSentence2,
104
- cand3: candidateSentence3,
105
- });
106
- }
107
-
108
- return (
109
- <>
110
- <h1>Semantic Similarity</h1>
111
- <h2>Measure how similar two sentences are in meaning.</h2>
112
-
113
- <div className='container'>
114
- <div className='textbox-container'>
115
- <textarea value={referenceSentence} rows={3} onChange={e => setReferenceSentence(e.target.value)}></textarea>
116
- <div className='candidates-container'>
117
- <div className='candidate-line-container'>
118
- <input type='text' value={candidateSentence1} onChange={e => setCandidateSentence1(e.target.value)}></input>
119
- <p className='output-score'>{output_1}</p>
120
- </div>
121
- <div className='candidate-line-container'>
122
- <input type='text' value={candidateSentence2} onChange={e => setCandidateSentence2(e.target.value)}></input>
123
- <p className='output-score'>{output_2}</p>
124
- </div>
125
- <div className='candidate-line-container'>
126
- <input type='text' value={candidateSentence3} onChange={e => setCandidateSentence3(e.target.value)}></input>
127
- <p className='output-score'>{output_3}</p>
128
- </div>
129
- </div>
130
- </div>
131
- </div>
132
-
133
- <button disabled={disabled} onClick={compute}>Compute</button>
134
-
135
- <div className='progress-bars-container'>
136
- {ready === false && (
137
- <label>Loading models... (this only runs once)</label>
138
- )}
139
- {progressItems.map(data => (
140
- <div key={data.file}>
141
- <Progress text={data.file} percentage={data.progress}/>
142
- </div>
143
- ))}
144
- </div>
145
-
146
- </>
147
- )
148
- }
149
-
150
- export default App
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/src/assets/react.svg DELETED
app/src/components/progress.jsx DELETED
@@ -1,10 +0,0 @@
1
- export default function Progress({ text, percentage }) {
2
- percentage = percentage ?? 0;
3
- return (
4
- <div className="progress-container">
5
- <div className='progress-bar' style={{ 'width': `${percentage}%` }}>
6
- {text} ({`${percentage.toFixed(2)}%`})
7
- </div>
8
- </div>
9
- );
10
- }
 
 
 
 
 
 
 
 
 
 
 
app/src/index.css DELETED
@@ -1,87 +0,0 @@
1
- :root {
2
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3
- line-height: 1.5;
4
- font-weight: 400;
5
-
6
- color-scheme: light dark;
7
- color: rgba(255, 255, 255, 0.87);
8
- background-color: #242424;
9
-
10
- font-synthesis: none;
11
- text-rendering: optimizeLegibility;
12
- -webkit-font-smoothing: antialiased;
13
- -moz-osx-font-smoothing: grayscale;
14
- -webkit-text-size-adjust: 100%;
15
- }
16
-
17
- a {
18
- font-weight: 500;
19
- color: #646cff;
20
- text-decoration: inherit;
21
- }
22
- a:hover {
23
- color: #535bf2;
24
- }
25
-
26
- body {
27
- margin: 0;
28
- display: flex;
29
- place-items: center;
30
- min-width: 320px;
31
- min-height: 100vh;
32
- }
33
-
34
- h1 {
35
- font-size: 3.2em;
36
- line-height: 1.1;
37
- }
38
-
39
- h1,
40
- h2 {
41
- margin: 8px;
42
- }
43
-
44
- textarea {
45
- font-size: 1.5em;
46
- padding: 0.6em;
47
- }
48
-
49
- input {
50
- font-size: 1.2em;
51
- padding: 0.5em;
52
- }
53
-
54
- button {
55
- border-radius: 8px;
56
- border: 1px solid transparent;
57
- padding: 0.6em 1.2em;
58
- font-size: 1em;
59
- font-weight: 500;
60
- font-family: inherit;
61
- background-color: #1a1a1a;
62
- cursor: pointer;
63
- transition: border-color 0.25s;
64
- }
65
- button:hover {
66
- border-color: #646cff;
67
- }
68
- button:focus,
69
- button:focus-visible {
70
- outline: 4px auto -webkit-focus-ring-color;
71
- }
72
- button[disabled] {
73
- cursor: not-allowed;
74
- }
75
-
76
- @media (prefers-color-scheme: light) {
77
- :root {
78
- color: #213547;
79
- background-color: #ffffff;
80
- }
81
- a:hover {
82
- color: #747bff;
83
- }
84
- button {
85
- background-color: #f9f9f9;
86
- }
87
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/src/main.jsx DELETED
@@ -1,10 +0,0 @@
1
- import React from 'react'
2
- import ReactDOM from 'react-dom/client'
3
- import App from './App.jsx'
4
- import './index.css'
5
-
6
- ReactDOM.createRoot(document.getElementById('root')).render(
7
- <React.StrictMode>
8
- <App />
9
- </React.StrictMode>,
10
- )
 
 
 
 
 
 
 
 
 
 
 
app/src/worker.js DELETED
@@ -1,120 +0,0 @@
1
- import { pipeline, env } from '@xenova/transformers';
2
-
3
- // Specify a custom location for models (defaults to '/models/').
4
- env.localModelPath = '/models/';
5
-
6
- // Disable the loading of remote models from the Hugging Face Hub:
7
- env.allowRemoteModels = false;
8
-
9
- // cache the model in the .cache directory in the current working directory
10
- env.cacheDir = './.cache';
11
-
12
- // Use the Singleton pattern to enable lazy construction of the pipeline.
13
- class SemanticSimilarityPipeline {
14
- static task = 'feature-extraction'; // follow model's task
15
- static model = 'Xenova/multi-qa-MiniLM-L6-cos-v1'; //https://huggingface.co/Xenova/multi-qa-MiniLM-L6-cos-v1
16
- static instance = null;
17
-
18
- static async getInstance(progress_callback = null) {
19
- if (this.instance === null) {
20
- this.instance = pipeline(this.task, this.model, { progress_callback });
21
- }
22
-
23
- return this.instance;
24
- }
25
- }
26
-
27
- function dotProduct(a, b) {
28
- if (a.length !== b.length) {
29
- throw new Error('Both arguments must have the same length');
30
- }
31
- let result = 0;
32
- for (let i = 0; i < a.length; i++) {
33
- result += a[i] * b[i]
34
- }
35
- return result.toFixed(3);
36
- }
37
-
38
- // Listen for messages from the main thread
39
- self.addEventListener('message', async (event) => {
40
- // Retrieve the similarity pipeline. When called for the first time,
41
- // this will load the pipeline and save it for future use.
42
- let extractor = await SemanticSimilarityPipeline.getInstance(x => {
43
- // We also add a progress callback to the pipeline so that we can track model loading.
44
- self.postMessage(x);
45
- });
46
- /* let extractor = await pipeline('feature-extraction', 'Xenova/multi-qa-MiniLM-L6-cos-v1', {
47
- progress_callback: x => {
48
- self.postMessage(x);
49
- }
50
- }); */
51
-
52
- // Actually compute the similarity
53
- let ref_embeddings = await extractor(event.data.refsent, {
54
- pooling: 'mean',
55
- normalize: true
56
- });
57
- console.log(ref_embeddings);
58
- let cand1_embeddings = await extractor(event.data.cand1, {
59
- pooling: 'mean',
60
- normalize: true
61
- });
62
- let cand2_embeddings = await extractor(event.data.cand2, {
63
- pooling: 'mean',
64
- normalize: true
65
- });
66
- let cand3_embeddings = await extractor(event.data.cand3, {
67
- pooling: 'mean',
68
- normalize: true
69
- });
70
- let output_1 = dotProduct(ref_embeddings.data, cand1_embeddings.data);
71
- let output_2 = dotProduct(ref_embeddings.data, cand2_embeddings.data);
72
- let output_3 = dotProduct(ref_embeddings.data, cand3_embeddings.data);
73
-
74
-
75
- // Send the output back to the main thread
76
- self.postMessage({
77
- status: 'update_1',
78
- output: output_1
79
- });
80
- self.postMessage({
81
- status: 'update_2',
82
- output: output_2
83
- });
84
- self.postMessage({
85
- status: 'update_3',
86
- output: output_3
87
- });
88
- self.postMessage({
89
- status: 'complete',
90
- });
91
- });
92
-
93
- /**
94
- * This JavaScript code is essentially using a machine learning model to perform semantic similarity tasks on some
95
- * input data. It uses the library "@xenova/transformers" which is a JavaScript implementation similar to Hugging
96
- * Face Transformers. It uses a specific model from Hugging Face ('Xenova/multi-qa-MiniLM-L6-cos-v1') to perform the
97
- * task.
98
-
99
- Here is a breakdown of the script:
100
-
101
- 1. **SemanticSimilarityPipeline class**: This is a singleton class, meaning it restricts the instantiation of a class
102
- to a single instance. It will create an instance of the pipeline using the specified task and model only if an
103
- instance does not already exist. This is done through the `getInstance` method. This method takes an optional
104
- progress_callback function, which would be called to report the progress of model loading.
105
-
106
- 2. **The `message` event listener**: This is listening for messages sent from the main thread. The event object it
107
- receives contains the data for computing the semantic similarity. When a message is received, it retrieves the
108
- singleton instance of the SemanticSimilarityPipeline, performs the computation, and then sends the result back to
109
- the main thread using `postMessage`.
110
-
111
- 3. **The `extractor` function call**: This uses the instance of the SemanticSimilarityPipeline to compute semantic
112
- similarity. It takes two arguments. The first one is a reference sentence (`event.data.refsent`). The second argument
113
- is an object that includes the candidate sentences (`cand1`, `cand2`, and `cand3`) and a callback function. This
114
- callback function is called after computing the similarity for each candidate sentence and it sends partial output
115
- back to the main thread.
116
-
117
- 4. **Sending result back to the main thread**: After the semantic similarity computation is complete, the output is
118
- sent back to the main thread using `postMessage`.
119
-
120
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/vite.config.js DELETED
@@ -1,7 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import react from '@vitejs/plugin-react'
3
-
4
- // https://vitejs.dev/config/
5
- export default defineConfig({
6
- plugins: [react()],
7
- })