How do I boost specific words at runtime with word boosting?#

This tutorial walks you through some of the advanced features for customization of Riva Speech Skills ASR Services at runtime with word boosting.

NVIDIA Riva Overview#

NVIDIA Riva is a GPU-accelerated SDK for building Speech AI applications that are customized for your use case and deliver real-time performance.
Riva offers a rich set of speech and natural language understanding services such as:

  • Automated speech recognition (ASR)

  • Text-to-Speech synthesis (TTS)

  • A collection of natural language processing (NLP) services, such as named entity recognition (NER), punctuation, intent classification.

In this tutorial, we will customize Riva ASR to boost specific words at runtime with word boosting.
To understand the basics of Riva ASR APIs, refer to Getting started with Riva ASR in Python.

For more information about Riva, refer to the Riva developer documentation.

Word boosting with Riva ASR APIs#

Word boosting is one of the customizations Riva offers. It allows you to bias the ASR engine to recognize particular words of interest at request time by giving them a higher score when decoding the output of the acoustic model.

Now, let’s use word boosting with Riva APIs for some sample audio clips with an OOTB (out-of-the-box) English pipeline.

Requirements and setup#

  1. Start the Riva Speech Skills server.
    Follow the instructions in the Riva Skills Quick Start Guide to deploy OOTB ASR models on the Riva Speech Skills server before running this tutorial. By default, only the English models are deployed.

  2. Install the Riva Client library.
    Follow the steps in the Requirements and setup for the Riva Client to install the Riva Client library.

Import the Riva client libraries#

Let’s import some of the required libraries, including the Riva Client libraries.

import io
import IPython.display as ipd
import grpc

import riva.client

Create a Riva client and connect to the Riva Speech API server#

The following URI assumes a local deployment of the Riva Speech API server is on the default port. In case the server deployment is on a different host or via a Helm chart on Kubernetes, use an appropriate URI.

auth = riva.client.Auth(uri='localhost:50051')

riva_asr = riva.client.ASRService(auth)

ASR inference without word boosting#

First, let’s run ASR on our sample audio clip without word boosting.

# Load a sample audio file from local disk
# This example uses a .wav file with LINEAR_PCM encoding.
path = "audio_samples/en-US_wordboosting_sample1.wav"
with io.open(path, 'rb') as fh:
    content = fh.read()
ipd.Audio(path)
# Creating RecognitionConfig
config = riva.client.RecognitionConfig(
  language_code="en-US",
  max_alternatives=1,
  enable_automatic_punctuation=True,
  audio_channel_count = 1
)

# ASR Inference call with Recognize 
response = riva_asr.offline_recognize(content, config)
asr_best_transcript = response.results[0].alternatives[0].transcript
print("ASR Transcript without Word Boosting:", asr_best_transcript)

As you can see, ASR is having a hard time recognizing domain specific terms like AntiBERTa and ABlooper.

Now, let’s use word boosting to try to improve ASR for these domain specific terms.

ASR inference with word boosting#

Let’s look at how to add the boosted words to RecognitionConfig with SpeechContext. (For more information about SpeechContext, refer to the docs here). The simplest way to add word boosting is to use function riva.client.add_word_boosting_to_config().

# Creating SpeechContext for word boosting
boosted_lm_words = ["AntiBERTa", "ABlooper"]
boosted_lm_score = 20.0
riva.client.add_word_boosting_to_config(config, boosted_lm_words, boosted_lm_score)

# ASR Inference call with Recognize 
response = riva_asr.offline_recognize(content, config)
asr_best_transcript = response.results[0].alternatives[0].transcript
print("ASR Transcript with Word Boosting:", asr_best_transcript)

As you can see, with word boosting, ASR is able to correctly transcribe the domain specific terms AntiBERTa and ABlooper.

Boost Score: The recommended range for the boost score is 20 to 100. The higher the boost score, the more biased the ASR engine is towards this word.
OOV Word Boosting: OOV words can also be word boosted; in the exact same way as in-vocabulary words, as described above.

Boosting different words at different levels#

With Riva ASR, we can also have different boost values for different words. For example, here AntiBERTa is boosted by 10 and ABlooper is boosted by 20:

# Load a sample audio file from local disk
# This example uses a .wav file with LINEAR_PCM encoding.
path = "audio_samples/en-US_wordboosting_sample1.wav"
with io.open(path, 'rb') as fh:
    content = fh.read()
ipd.Audio(path)
# Creating RecognitionConfig
config = riva.client.RecognitionConfig(
  language_code="en-US",
  max_alternatives=1,
  enable_automatic_punctuation=True,
  audio_channel_count = 1
)
riva.client.add_word_boosting_to_config(config, ["AntiBERTa"], 10.)
riva.client.add_word_boosting_to_config(config, ["ABlooper"], 20.)

# ASR Inference call with Recognize 
response = riva_asr.offline_recognize(content, config)
asr_best_transcript = response.results[0].alternatives[0].transcript
print("ASR Transcript with Word Boosting:", asr_best_transcript)

Negative word boosting for undesired words#

We can even use word boosting to discourage prediction of some words, by using negative boost scores.

Let’s load a sample audio file and get the transcription results from it without any word boosting

# Load a sample audio file from local disk
# This example uses a .wav file with LINEAR_PCM encoding.
path = "audio_samples/en-US_wordboosting_sample3.wav"
with io.open(path, 'rb') as fh:
    content = fh.read()
ipd.Audio(path)
# Creating RecognitionConfig
config = riva.client.RecognitionConfig(
  language_code="en-US",
  max_alternatives=1,
  enable_automatic_punctuation=True,
  audio_channel_count = 1
)

# ASR Inference call with Recognize 
response = riva_asr.offline_recognize(content, config)
asr_best_transcript = response.results[0].alternatives[0].transcript
print("ASR Transcript without Word Boosting:", asr_best_transcript)

Now, let us get the transcription results with negative word boosting for the word been.

# Creating RecognitionConfig
config = riva.client.RecognitionConfig(
  language_code="en-US",
  max_alternatives=1,
  enable_automatic_punctuation=True,
  audio_channel_count = 1
)
riva.client.add_word_boosting_to_config(config, ["been"], -100.)

# ASR Inference call with Recognize 
response = riva_asr.offline_recognize(content, config)
asr_best_transcript = response.results[0].alternatives[0].transcript
print("ASR Transcript with Negative Word Boosting:", asr_best_transcript)

As you can see, the word been was not predicted this time. Also note that in this case, be was predicted in its place. In some cases, no word might be predicted.

Now let us see how we can combine negative and positive word boosting:
Let us combine the negative word boosting from above example, with positive word boosting to predict the word middle instead of little. We perform positive word boosting, as we did in earlier examples, for word middle. Note that we are using the same config instance, that we created in the above example for negative word boosting for little. So it already has the SpeechContext instance for little. So, now, we just need to add a SpeechContext instance for positive word boosting for middle.

Now, let us see how we can combine negative and positive word boosting:
Let us combine the negative word boosting from the above example with positive word boosting to predict the word bin instead of been. We perform positive word boosting, as we did in earlier examples, by adding a new SpeechContext instance for bin to the RecognitionConfig instance config. Note that we are using the same config instance that we created in the above example for negative word boosting for been. So, it already has the SpeechContext instance for been. Now, we just need to add a SpeechContext instance for positive word boosting for bin.

# Creating SpeechContext for Word Boosting
positive_boosted_lm_word = "bin"
positive_boosted_lm_score = 200.0
riva.client.add_word_boosting_to_config(config, [positive_boosted_lm_word], positive_boosted_lm_score)

# ASR Inference call with Recognize 
response = riva_asr.offline_recognize(content, config)
asr_best_transcript = response.results[0].alternatives[0].transcript
print("ASR Transcript with Negative and Positive Word Boosting:", asr_best_transcript)

As you can see, in this example, we were able to generate the transcript with bin instead of been, by combining negative and positive word boosting.

Note:

  • There is no limit to the number of words that can be boosted. You should see no impact on latency for all requests, even for ~100 boosted words, except for the first request, which is expected.

  • Boosting phrases or a combination of words is not yet fully supported (but do work). We will revisit finalizing this support in an upcoming release.

  • By default, no words are boosted on the server side. Only words passed by the client are boosted.

Information about word boosting can also be found in the documentation here.

Go deeper into Riva capabilities#

Additional Riva Tutorials#

Checkout more Riva tutorials here to understand how to use some of the advanced features of Riva ASR, including customizing ASR for your specific needs.

Sample Applications#

Riva comes with various sample applications. They demonstrate how to use the APIs to build various applications. Refer to Riva Sampple Apps for more information.

Additional Resources#

For more information about each of the Riva APIs and their functionalities, refer to the documentation.