Skip to content
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

Wasm test page UI for translating b/w non-English language pairs #231

Merged
merged 2 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 18 additions & 88 deletions wasm/README.md
Original file line number Diff line number Diff line change
@@ -1,95 +1,25 @@
# Using Bergamot Translator in JavaScript

Instructions in this document assume current-directory to be
[wasm](https://github.com/browsermt/bergamot-translator/tree/main/wasm) within
bergamot-translator source.

The example file `bergamot.html` in the folder `test_page` demonstrates how to
use the bergamot translator in JavaScript via a `<script>` tag.

## Pre-requisites

**Download files required for translation**

Please note that [Using JS APIs](#using-js-apis) and [Demo](#demo) section below assumes that the [bergamot project specific model files](https://github.com/mozilla-applied-ml/bergamot-models) are already downloaded and present in the `test_page` folder. If this is not done then use following instructions to do so:

```bash
cd test_page
git clone --depth 1 --branch main --single-branch https://github.com/mozilla-applied-ml/bergamot-models
mkdir models
cp -rf bergamot-models/prod/* models
gunzip models/*/*
```
All the instructions below are meant to run from the current directory.

## Using JS APIs

```js
// The model configuration as YAML formatted string. For available configuration options, please check: https://marian-nmt.github.io/docs/cmd/marian-decoder/
// This example captures some of the most relevant options
const modelConfig = `beam-size: 1
normalize: 1.0
word-penalty: 0
max-length-break: 128
mini-batch-words: 1024
workspace: 128
max-length-factor: 2.0
skip-cost: true
cpu-threads: 0
quiet: true
quiet-translation: true
gemm-precision: int8shift
`;

// Download model, shortlist and vocabulary files and read them into buffers
const modelFile = `models/esen/model.esen.intgemm.alphas.bin`;
const shortlistFile = `models/esen/lex.50.50.esen.s2t.bin`;
const vocabFiles = [`models/${languagePair}/vocab.${vocabLanguagePair}.spm`,
`models/${languagePair}/vocab.${vocabLanguagePair}.spm`];
const uniqueVocabFiles = new Set(vocabFiles);

// Please refer to bergamot.html in test_page folder for downloadAsArrayBuffer function
const downloadedBuffers = await Promise.all([downloadAsArrayBuffer(modelFile), downloadAsArrayBuffer(shortlistFile)]);
const downloadedVocabBuffers = [];
for (let item of uniqueVocabFiles.values()) {
downloadedVocabBuffers.push(await downloadAsArrayBuffer(item));
}

const modelBuffer = downloadedBuffers[0];
const shortListBuffer = downloadedBuffers[1];
Please refer to the file `test_page/js/worker.js` that demonstrates how to use the bergamot translator in JavaScript via a `<script>` tag.

// Construct AlignedMemory instances from the buffers
var alignedModelMemory = constructAlignedMemoryFromBuffer(modelBuffer, 256); // Please refer to bergamot.html in test_page folder for this function
var alignedShortlistMemory = constructAlignedMemoryFromBuffer(shortListBuffer, 64); // Please refer to bergamot.html in test_page folder for this function
var alignedVocabsMemoryList = new Module.AlignedMemoryList;
downloadedVocabBuffers.forEach(item => alignedVocabsMemoryList.push_back(constructAlignedMemoryFromBuffer(item, 64)));
## Demo

// Instantiate the Translation Service
const translationService = new Module.Service(modelConfig, alignedModelMemory, alignedShortlistMemory, alignedVocabsMemoryList);
* Download bergamot model files required for translation

// Instantiate the arguments of translate() API i.e. ResponseOptions and input (vector<string>)
const responseOptions = new Module.ResponseOptions();
const input = new Module.VectorString;
Use following instructions to download [model files](https://github.com/mozilla/firefox-translations-models/) (make sure that `git-lfs` is installed and initialized before running these instructions):

// Initialize the input
input.push_back("Hola"); input.push_back("Mundo");

// translate the input; the result is a vector<Response>
const result = translationService.translate(input, responseOptions);

// Print original and translated text from each entry of vector<Response>
for (let i = 0; i < result.size(); i++) {
console.log(' original=' + result.get(i).getOriginalText() + ', translation=' + result.get(i).getTranslatedText());
}

// Don't forget to clean up the instances
translationService.delete();
responseOptions.delete();
input.delete();
```

## Demo

* Make sure that you followed [Pre-requisites](#pre-requisites) instructions before moving forward.
```bash
cd test_page
git clone --depth 1 --branch main --single-branch https://github.com/mozilla/firefox-translations-models/
mkdir models
cp -rf firefox-translations-models/models/prod/* models
cp -rf firefox-translations-models/models/dev/* models
gunzip models/*/*
```

* Start the test webserver (ensure you have the latest nodejs installed)
```bash
Expand All @@ -114,10 +44,10 @@ input.delete();

* Browse to the following page:
```
http://localhost:8000/bergamot.html
http://localhost:80
```

* Run some translations:
* Choose a model and press `Load Model`
* Type a sentence to be translated in the `From` textbox and press `Translate`
* See the results in the `To` and `Log` textboxes
* Perform translations:
* Choose the source and target languages using `From` and `To` dropdowns.
* Type a sentence to be translated in the `From` textbox.
* See the result in the `To` textbox.
61 changes: 58 additions & 3 deletions wasm/test_page/bergamot-httpserver.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,42 @@
require(__dirname + '/helper.js');

const http = require('http');
const https = require('https')
const express = require('express');
const app = express();
const server = http.createServer(app);
const fs = require('fs');
const url = require('url');
const nocache = require('nocache');
const cors = require('cors');
const path = require('path');

let port = 8000;
if (process.argv[2]) {
port = process.argv[2];
}

let skipssl = 0;
if (process.argv[3]) {
skipssl = process.argv[3];
}

let certpath = "/etc/letsencrypt";
if (process.argv[4]) {
certpath = process.argv[4];
}

app.use(cors())
app.use(nocache());

app.get('/', cors(), function(req, res) {
if (!req.secure && skipssl != 1) {
return res.redirect("https://" + req.headers.host + req.url);
}
res.sendFile(path.join(__dirname + '/index.html'));
res.header('Cross-Origin-Embedder-Policy','require-corp');
res.header('Cross-Origin-Opener-Policy','same-origin');
res.header('Cross-Origin-Resource-Policy','same-origin');
});

app.get('/*.*' , cors(), function(req, res) {
var options = url.parse(req.url, true);
var mime = Helper.getMime(options);
Expand All @@ -34,5 +58,36 @@ function serveFile(res, pathName, mime) {
});
}

if (skipssl != 1){
https.createServer({
key: fs.readFileSync(`${certpath}/privkey.pem`),
cert: fs.readFileSync(`${certpath}/cert.pem`),
ca: fs.readFileSync(`${certpath}/chain.pem`),
},
app
).listen(443, () => {
console.log('Listening https port 443')
})
}

const Helper = {
types: {
"wasm" : "application/wasm"
, "js" : "application/javascript"
, "html" : "text/html"
, "htm" : "text/html"
, "ico" : "image/vnd.microsoft.icon"
, "css" : "text/css"
},
getMime: function(u) {
var ext = this.getExt(u.pathname).replace('.', '');
return this.types[ext.toLowerCase()] || 'application/octet-stream';
},
getExt: function(path) {
var i = path.lastIndexOf('.');
return (i < 0) ? '' : path.substr(i);
}
};

server.listen(port);
console.log(`HTTP and BinaryJS server started on port ${port}`);
console.log(`HTTP and BinaryJS server started on port ${port}`);
66 changes: 0 additions & 66 deletions wasm/test_page/bergamot.html

This file was deleted.

54 changes: 0 additions & 54 deletions wasm/test_page/bergamot.js

This file was deleted.

Loading