Package Exports
- question-answering
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (question-answering) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Question Answering for Node.js
Production-ready Question Answering directly in Node.js, with only 3 lines of code!
This package leverages the power of the tokenizers library (built with Rust) to process the input text. It then uses TensorFlow.js to run the DistilBERT-cased model fine-tuned for Question Answering (87.1 F1 score on SQuAD v1.1 dev set, compared to 88.7 for BERT-base-cased).
Installation
npm install question-answering
Simple example
This example is running the model locally. To do so, you first need to download the model and vocabulary file:
npx question-answering download
By default, the model and vocabulary are downloaded inside a
.models
directory at the root of your project; you can provide a custom directory by using the--dir
option of the CLI.
import { QAClient } from "question-answering";
const text = `
Super Bowl 50 was an American football game to determine the champion of the National Football League (NFL) for the 2015 season.
The American Football Conference (AFC) champion Denver Broncos defeated the National Football Conference (NFC) champion Carolina Panthers 24–10 to earn their third Super Bowl title. The game was played on February 7, 2016, at Levi's Stadium in the San Francisco Bay Area at Santa Clara, California.
As this was the 50th Super Bowl, the league emphasized the "golden anniversary" with various gold-themed initiatives, as well as temporarily suspending the tradition of naming each Super Bowl game with Roman numerals (under which the game would have been known as "Super Bowl L"), so that the logo could prominently feature the Arabic numerals 50.
`;
const question = "Who won the Super Bowl?";
const qaClient = await QAClient.fromOptions();
const answer = await qaClient.predict(question, text);
console.log(answer); // { text: 'Denver Broncos', score: 0.3 }
Advanced
Using a remote model with TensorFlow Serving
You may prefer to host your model on a dedicated server. It's possible by simply passing the server endpoint as the path
option and remote
to true
. Here is a simple example using Docker locally:
# Inside our project root, download DistilBERT-cased to its default `.models` location
npx question-answering download
# Download the TensorFlow Serving Docker image
docker pull tensorflow/serving
# Start TensorFlow Serving container and open the REST API port.
# Notice that in the `target` path we add a `/1`:
# this is required by TFX which is expecting the models to be "versioned"
docker run -t --rm -p 8501:8501 \
--mount type=bind,source="$(pwd)/.models/distilbert-cased/",target="/models/cased/1" \
-e MODEL_NAME=cased \
tensorflow/serving &
Then in your code:
const qaClient = await QAClient.fromOptions({
model: { path: "http://localhost:8501/v1/models/cased", cased: true, remote: true }
});
Using a different model
You can choose to use the uncased version of DistilBERT instead.
First, download the uncased model:
npx question-answering download distilbert-uncased
You can then instantiate a QAClient
by specifying some options:
const qaClient = await QAClient.fromOptions({
model: { path: "./.models/distilbert-uncased", cased: false },
vocabPath: "./.models/distilbert-uncased/vocab.txt"
});
You can also choose to use a custom model and pass it to QAClient.fromOptions
, the same way than for DistilBERT-uncased. Check the QAOptions
interface for the complete list of options. And you can still host it remotely.
Using a custom tokenizer
You can provide your own tokenizer instance to QAClient.fromOptions
, as long as it implements the BERTWordPieceTokenizer
methods.
Performances
Thanks to the native execution of SavedModel format in TFJS, the performance of such models is similar to the one using TensorFlow in Python.
Specifically, here are the results of a benchmark using question-answering
completely locally, with a (pseudo-)remote model server (i.e. local Docker), and using the Question Answering pipeline in the transformers
library.
Shorts texts are texts between 500 and 1000 characters, long texts are between 4000 and 5000 characters. You can check the
question-answering
benchmark script here (the transformers
one is equivalent). Benchmark run on a standard 2019 MacBook Pro running on macOS 10.15.2.