Boost Transcription Accuracy with LeMUR (LeMUR Custom Vocab)

This Cookbook is designed to help you transcribe audio files using the AssemblyAI API and boost transcription accuracy using a custom vocabulary list and LeMUR. Custom vocabulary can include company names, industry-specific terms, and other rare words that might not be accurately transcribed by pre-trained models. For example, a company name like Sprinklr may be transcribed incorrectly, and this is where customer vocabulary boosting can help.

Quickstart

1import assemblyai
2from json import loads
3from termcolor import colored
4
5def correct_sentence(sentence, word_list = []):
6 prompt = """
7 You are an expert in correcting speech-to-text model outputs given a list of custom vocabulary words.
8 You will be given a sentence from a transcript.
9 You will also be given a list of custom vocabulary word that could be in the sentence.
10 Your job is to identify any words from the custom vocabulary list that are in the sentence and correct them if they are spelled incorrectly.
11 Only focus on spelling errors, you do not need to make corrections for miscased words.
12
13 Only focus on corrections that are related to the custom vocabulary list.
14 If there are no words from the custom vocabulary list in the sentence, you should return an empty array.
15 If there are words from the list, return the original word, the corrected word, and your confidence in the correction.
16
17 Return your answer in JSON with no explanation. The JSON should have the following format:
18 [{
19 "original_word": "word1",
20 "corrected_word": "word2",
21 "confidence": 0.8
22 }]
23 """
24
25 response = assemblyai.Lemur().task(
26 prompt=prompt,
27 input_text="Sentence: {}\nWord List: {}".format(sentence, ", ".join(word_list)),
28 final_model=assemblyai.LemurModel.claude3_5_sonnet # Use .claude3_haiku for a faster, more cost-effective option.
29 )
30
31 return response.response
32
33def correct_transcript(transcript, word_list = []):
34 sentences = transcript.get_sentences()
35 new_transcript = ""
36
37 for sentence in sentences:
38
39 # Optional: You can include word confidence scores as part of your input to guide LeMUR to incorrectly spelled words.
40 # sentence_str = ""
41 # for word in sentence.words:
42 # sentence_str += word.text + f" [{word.confidence}] "
43
44 corrections = correct_sentence(sentence.text, word_list)
45 corrections_json = loads(corrections)
46 corrected_sentence = sentence.text
47
48 for correction in corrections_json:
49 if correction["confidence"] > 0.25: # Configure as needed.
50 corrected_sentence = corrected_sentence.replace(correction["original_word"], correction["corrected_word"])
51 else:
52 print(colored("Confidence is less than 0.25", correction["original_word"], correction["corrected_word"], correction["confidence"], "red"))
53
54 new_transcript += corrected_sentence + " "
55
56 if len(corrections_json) > 0:
57 print("Identified sentence to correct: ", colored(sentence.text, "yellow"))
58
59 print()
60 return new_transcript
61
62assemblyai.settings.api_key = "YOUR_API_KEY"
63transcriber = assemblyai.Transcriber()
64
65transcript = transcriber.transcribe("https://drive.google.com/u/0/uc?id=1E1UUnabkXH-wN-CGbr-zd9dT_izZg1e6&export=download")
66
67word_list = [
68 'Azj-Kahet',
69 'Neferess',
70 "Ny'alotha",
71 "Xal'atath"
72 "Ansurek"
73]
74
75print(transcript.text)
76print()
77print(correct_transcript(transcript, word_list))

Getting Started

Before we begin, make sure you have an AssemblyAI account and an API key. You can sign up for an AssemblyAI account and get your API key from your dashboard.

Side Note: Costs

We’ve optimized the LeMUR prompt to minimize the number of output tokens produced by the model, which will reduce the overall cost of this solution significantly, but if you do want to calculate the total number of input / output tokens and cost associated with them, please use our LeMUR pricing cookbook as a reference on how to do so.

Step-by-Step Instructions

Now let’s install the AssemblyAI SDK and the Termcolor library, which will be used for showing which corrections LeMUR has made to the transcript.

$pip install -U assemblyai termcolor

Then we’ll import the SDK and set our AssemblyAI API key.

1import assemblyai
2
3assemblyai.settings.api_key = "YOUR_API_KEY"

Next, we’ll transcribe our file and save it for later use with LeMUR.

1transcriber = assemblyai.Transcriber()
2
3transcript = transcriber.transcribe("https://drive.google.com/u/0/uc?id=1E1UUnabkXH-wN-CGbr-zd9dT_izZg1e6&export=download")

Now we’ll define our first function for this use case. This function will correct a given sentence using LeMUR with the provided custom vocab list. We’ll then call this function for each sentence in our transcript to correct specific words. Please note, though, that this means each sentence will require another request to LeMUR, which may cause you to hit request per minute (RPM) limits and receive an error. If you do end up receiving RPM errors often, please reach out to support@assemblyai.com to have your RPM limit increased.

1def correct_sentence(sentence, word_list = []):
2 prompt = """
3 You are an expert in correcting speech-to-text model outputs given a list of custom vocabulary words.
4 You will be given a sentence from a transcript.
5 You will also be given a list of custom vocabulary word that could be in the sentence.
6 Your job is to identify any words from the custom vocabulary list that are in the sentence and correct them if they are spelled incorrectly.
7 Only focus on spelling errors, you do not need to make corrections for miscased words.
8
9 Only focus on corrections that are related to the custom vocabulary list.
10 If there are no words from the custom vocabulary list in the sentence, you should return an empty array.
11 If there are words from the list, return the original word, the corrected word, and your confidence in the correction.
12
13 Return your answer in JSON with no explanation. The JSON should have the following format:
14 [{
15 "original_word": "word1",
16 "corrected_word": "word2",
17 "confidence": 0.8
18 }]
19 """
20
21 response = assemblyai.Lemur().task(
22 prompt=prompt,
23 input_text="Sentence: {}\nWord List: {}".format(sentence, ", ".join(word_list)),
24 final_model=assemblyai.LemurModel.claude3_5_sonnet # Use .claude3_haiku for a faster, more cost-effective option.
25 )
26
27 return response.response

Then we can define our second function. This function will extract all of the sentences from our transcript and pass them to LeMUR with our custom vocabulary list for correction. We’ll be importing termcolor to show which words have been corrected with LeMUR.

1from json import loads
2from termcolor import colored
3
4def correct_transcript(transcript, word_list = []):
5 sentences = transcript.get_sentences()
6 new_transcript = ""
7
8 for sentence in sentences:
9
10 # Optional: You can include word confidence scores as part of your input to guide LeMUR to incorrectly spelled words.
11 # sentence_str = ""
12 # for word in sentence.words:
13 # sentence_str += word.text + f" [{word.confidence}] "
14
15 corrections = correct_sentence(sentence.text, word_list)
16 corrections_json = loads(corrections)
17 corrected_sentence = sentence.text
18
19 for correction in corrections_json:
20 if correction["confidence"] > 0.25: # Configure as needed.
21 corrected_sentence = corrected_sentence.replace(correction["original_word"], correction["corrected_word"])
22 else:
23 print(colored("Confidence is less than 0.25", correction["original_word"], correction["corrected_word"], correction["confidence"], "red"))
24
25 new_transcript += corrected_sentence + " "
26
27 if len(corrections_json) > 0:
28 print("Identified sentence to correct: ", colored(sentence.text, "yellow"))
29
30 print()
31 return new_transcript

Run your Example

Now you can try an example using our sample MP3 file and some word corrections. We chose to use some media with a lot of unique words, a World of Warcraft trailer, to help showcase how this solution can account for multiple ways that a unique word might be mis-transcribed initially. Below is the original transcript, the corrections made, and the final corrected transcript for comparison.

1word_list = [
2 'Azj-Kahet',
3 'Neferess',
4 "Ny'alotha",
5 "Xal'atath"
6 "Ansurek"
7]
8
9print(transcript.text)
10print()
11print(correct_transcript(transcript, word_list))
Slender is the strand that guides our destiny, known only by true sacrifice. In our kingdom of Ajkahet, no one understood this sacrifice more than Queen Neferis, my mother. I saw this when the Black Empire came to conscript us for their last stand at Nyalofa. My mother refused them for this treachery. Your line will sever itself. This kingdom will wither with the waning of your words. Her strength defined us that day. And in that moment, we felt destined for greatness. But in the years that followed, our greatness was tarnished. Look at them out there. Wretched, starving. I am not immune to our people's suffering. I believe better days will come. Nothing if you keep failing to seize the moment. What was the point of you freeing our future, only to leave us buried in the past? You comprehend so little. There is much for you to learn before you can be queen. Mother. Mother. Mother. Answeric, are you seeing this? You have heard my voice in your dreams, great queen. The harbinger. Yes. Of the empire that was. But the old gods are dead. The empire lies in ashes, and a shadow has fallen on your kingdom. But the blood of the old gods can make your people powerful again. Your brain could last for eternity. All you have to do is take my hand. Your words are tempting, but the cost is too great. I would never risk my kingdom for such power. Mother, who are you talking to? Oh, ghosts, dearest. As always, they are my ready council. I'm not sorry for what I said. I only want our people to be great once more. Greatness is fleeting. What we must do now is endure. Your time will come, child, but only when you are ready. What you done? You're not the only one seeing ghosts, mother. How sad to have a queen so wise and yet so ignorant to the call of destiny. You. Her name is Xalatath. You heard your chance. Motherhood. With this power, ash cahet is unbound. We will rise, we will conquer. And together we will finally claim our destiny. Long live Queen Anzarak. It.
Found correction: In our kingdom of Ajkahet, no one understood this sacrifice more than Queen Neferis, my mother.
Found correction: I saw this when the Black Empire came to conscript us for their last stand at Nyalofa.
Found correction: Answeric, are you seeing this?
Found correction: Her name is Xalatath.
Found correction: With this power, ash cahet is unbound.
Slender is the strand that guides our destiny, known only by true sacrifice. In our kingdom of Azj-Kahet, no one understood this sacrifice more than Queen Neferess, my mother. I saw this when the Black Empire came to conscript us for their last stand at Ny'alotha. My mother refused them for this treachery. Your line will sever itself. This kingdom will wither with the waning of your words. Her strength defined us that day. And in that moment, we felt destined for greatness. But in the years that followed, our greatness was tarnished. Look at them out there. Wretched, starving. I am not immune to our people's suffering. I believe better days will come. Nothing if you keep failing to seize the moment. What was the point of you freeing our future, only to leave us buried in the past? You comprehend so little. There is much for you to learn before you can be queen. Mother. Mother. Mother. Ansurek, are you seeing this? You have heard my voice in your dreams, great queen. The harbinger. Yes. Of the empire that was. But the old gods are dead. The empire lies in ashes, and a shadow has fallen on your kingdom. But the blood of the old gods can make your people powerful again. Your brain could last for eternity. All you have to do is take my hand. Your words are tempting, but the cost is too great. I would never risk my kingdom for such power. Mother, who are you talking to? Oh, ghosts, dearest. As always, they are my ready council. I'm not sorry for what I said. I only want our people to be great once more. Greatness is fleeting. What we must do now is endure. Your time will come, child, but only when you are ready. What you done? You're not the only one seeing ghosts, mother. How sad to have a queen so wise and yet so ignorant to the call of destiny. You. Her name is Xal'atath. You heard your chance. Motherhood. With this power, Azj-Kahet is unbound. We will rise, we will conquer. And together we will finally claim our destiny. Long live Queen Anzarak. It.