Chapter 32
Get started with Chirp 3 Transcription
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.Get started with Chirp 3 Transcription
| Authors |
|---|
| Katie Nguyen |
| Holt Skinner |
Overview
Chirp 3
This notebook introduces Chirp 3, Google's model for converting speech to text in multiple languages.
In this tutorial, you'll learn how to use the Speech-to-Text API V2 to:
- Transcribe an audio file with batch speech recognition
- Perform a language-agnostic transcription
- Use Chirp 3 for speaker diarization
- Perform streaming speech recognition
Get started
Install the Speech SDK and other required packages
%pip install --upgrade --quiet google-cloud-speech ipywebrtcAuthenticate your notebook environment (Colab only)
If you're running this notebook on Google Colab, run the cell below to authenticate your environment.
import sys
if "google.colab" in sys.modules:
from google.colab import auth
auth.authenticate_user()Import libraries
import json
import os
import re
from collections.abc import Generator
from IPython.display import HTML, Audio, display
from google.api_core.client_options import ClientOptions
from google.cloud.speech_v2 import SpeechClient
from google.cloud.speech_v2.types import cloud_speech
from ipywebrtc import AudioRecorder, CameraStreamSet Google Cloud project information
To get started using the Speech-to-Text API, you must have an existing Google Cloud project and enable the API.
Learn more about setting up a project and a development environment.
Please note the available regions for Chirp 3, see documentation.
# fmt: off
PROJECT_ID = "[your-project-id]" # @param {type: "string", placeholder: "[your-project-id]", isTemplate: true}
# fmt: on
if not PROJECT_ID or PROJECT_ID == "[your-project-id]":
PROJECT_ID = str(os.environ.get("GOOGLE_CLOUD_PROJECT"))
STT_LOCATION = "us" # @param {type: "string"}! gcloud config set project {PROJECT_ID}
! gcloud auth application-default login -q
! gcloud auth application-default set-quota-project {PROJECT_ID}Create client
Initiate the API endpoint and the Speech-to-Text client and define key constants.
client = SpeechClient(
client_options=ClientOptions(api_endpoint=f"{STT_LOCATION}-speech.googleapis.com")
)
recognizer = client.recognizer_path(PROJECT_ID, STT_LOCATION, "_")
model = "chirp_3"
# Set a timeout for the batch recognition operation
MAX_AUDIO_LENGTH_SECS = 8 * 60 * 60Define helper functions
def print_transcript(results: list[cloud_speech.SpeechRecognitionResult]) -> None:
for result in results:
display(
HTML(
f"""<div style="word-break: break-all;">{result.alternatives[0].transcript}</div>"""
)
)
def generate_audio_chunks(
audio_content: bytes, chunk_size: int
) -> Generator[bytes, None, None]:
"""Splits a byte string (like audio data) into smaller, equal-sized chunks.
Args:
audio_content: The raw byte data of the audio.
chunk_size: The desired size for each audio chunk in bytes.
Yields:
A series of audio chunks.
"""
# Loop through the audio content, stepping by chunk_size each time
for start_index in range(0, len(audio_content), chunk_size):
# The end_index is the start_index plus the chunk size
end_index = start_index + chunk_size
# Yield the slice of audio data for the current chunk
yield audio_content[start_index:end_index]
def group_utterances_by_speaker_from_file(json_file_path: str) -> dict:
"""Reads a JSON file containing transcribed words and groups them into sentences spoken by each speaker."""
with open(json_file_path, encoding="utf-8") as f:
json_data_string = f.read()
words_regex = r'"words":\s*(\[.*?\])'
match = re.search(words_regex, json_data_string, re.DOTALL)
words_list = json.loads(match.group(1))
dialogue = []
current_speaker = None
current_utterance_words = []
current_speaker = words_list[0]["speakerLabel"]
for item in words_list:
word = item["word"]
speaker = item["speakerLabel"]
# Check if the speaker has changed
if speaker != current_speaker:
dialogue.append(
{"speaker": current_speaker, "text": " ".join(current_utterance_words)}
)
# Start a new utterance
current_speaker = speaker
current_utterance_words = [word]
else:
# Continue the current utterance
current_utterance_words.append(word)
# Add the final pending utterance
if current_speaker is not None:
dialogue.append(
{"speaker": current_speaker, "text": " ".join(current_utterance_words)}
)
return {"dialogue": dialogue}Transcribe using Chirp 3
Online/Synchronous speech recognition
You can use online (synchronous) speech recognition for audio files less than 1 minute long.
For this first request, Run the following cell to download and play the audio you'll be transcribing. If you'd like to use a different audio clip, modify the audio_url variable below.
audio_url = "https://storage.googleapis.com/cloud-samples-data/generative-ai/audio/audio_summary_clean_energy_short.mp3"
audio_filename = os.path.basename(audio_url)
! wget {audio_url} -O {audio_filename}
display(Audio(filename=audio_filename))Now, you'll send the recognize request. The transcription will be returned as part of the response and displayed in HTML for better visualization in this notebook.
config = cloud_speech.RecognitionConfig(
auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
model=model,
language_codes=["en-US"],
)
with open(audio_filename, "rb") as f:
audio_content = f.read()
request = cloud_speech.RecognizeRequest(
recognizer=recognizer,
config=config,
content=audio_content,
)
response = client.recognize(request=request)
print_transcript(response.results)Perform a language-agnostic transcription
In this next request, you'll perform a language-agnostic transcription. This means that Chirp 3 will automatically identify and transcribe the dominant language spoken in the audio, which is essential for multilingual applications.
In this next example, you'll use a Spanish audio clip saved in Cloud Storage. To see a full list of the languages available for transcription, check the documentation.
audio_url = (
"https://storage.googleapis.com/cloud-samples-data/generative-ai/audio/spanish.wav"
)
audio_gcs_uri = audio_url.replace("https://storage.googleapis.com/", "gs://")
display(Audio(url=audio_url))This request is the similar to the previous one, except this time, you'll set language_codes=["auto"].
config = cloud_speech.RecognitionConfig(
auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
model=model,
language_codes=["auto"],
)
request = cloud_speech.RecognizeRequest(
recognizer=recognizer,
config=config,
uri=audio_gcs_uri,
)
response = client.recognize(request=request)
print_transcript(response.results)Speaker Diarization (Batch Recognition)
Chirp 3 also supports speaker diarization, which means it can automatically identify the different speakers in a single-channel audio sample. See the documentation for a list of supported available languages for diarization.
In this example, you'll also use the batch_recognize method to transcribe an audio file in Cloud Storage and save the output in Cloud Storage.
audio_url = "https://storage.googleapis.com/cloud-samples-data/generative-ai/audio/Chirp-3-Docs-Dive.mp3"
audio_gcs_uri = audio_url.replace("https://storage.googleapis.com/", "gs://")
display(Audio(url=audio_url))
gcs_output_folder = "gs://[your-bucket-path]" # @param {type: "string"}In order to enable speaker diarization, set the diarization_config in the features parameter of the RecognitionConfig.
You'll also set your gcs_output_folder in a RecognitionOutputConfig so the transcription will be saved in Cloud Storage. To display the transcription, you'll copy the output JSON file and use a helper function to format it.
config = cloud_speech.RecognitionConfig(
auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
features=cloud_speech.RecognitionFeatures(
diarization_config=cloud_speech.SpeakerDiarizationConfig(),
),
model=model,
language_codes=["en-US"],
)
files = [cloud_speech.BatchRecognizeFileMetadata(uri=audio_gcs_uri)]
request = cloud_speech.BatchRecognizeRequest(
recognizer=recognizer,
config=config,
files=files,
recognition_output_config=cloud_speech.RecognitionOutputConfig(
gcs_output_config=cloud_speech.GcsOutputConfig(uri=gcs_output_folder),
),
)
operation = client.batch_recognize(request=request)
response = operation.result(timeout=MAX_AUDIO_LENGTH_SECS)
transcript = response.results[audio_gcs_uri].uri
!gsutil cp {transcript} output.json
print(json.dumps(group_utterances_by_speaker_from_file("output.json"), indent=4))Streaming speech recognition
In the following cells you'll simulate transcribing text from an audio stream. To start, you'll record an audio clip with your microphone by running the following cell.
if "google.colab" in sys.modules:
from google.colab import output
output.enable_custom_widget_manager()
camera = CameraStream(constraints={"audio": True, "video": False})
recorder = AudioRecorder(stream=camera)
recorderOnce the audio is captured and you've stopped recording, you'll use FFmpeg to convert and save the clip to a MP3 file for processing.
with open("recording.webm", "wb") as f:
f.write(recorder.audio.value)
!ffmpeg -i recording.webm -vn -ar 44100 -ac 2 -f mp3 recording.mp3
audio_file = "recording.mp3"Now, you'll read the audio file and generate audio chunks to simulate streaming from a helper function. You'll then use the streaming_recognize method to get the transcription from each audio chunk with help from a generator function to correctly structure the data stream.
CHUNK_SIZE = 3200
recognition_config = cloud_speech.RecognitionConfig(
auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
language_codes=["auto"],
model=model,
)
def create_streaming_requests(
audio_file_path: str,
) -> Generator[cloud_speech.StreamingRecognizeRequest, None, None]:
"""Prepares and yields all necessary requests for streaming speech recognition.
First, it yields the configuration request, then it reads an audio file
and yields its content in chunks.
Args:
audio_file_path: The path to the local audio file.
Yields:
A stream of StreamingRecognizeRequest objects.
"""
# a. First, yield the initial configuration request.
config_request = cloud_speech.StreamingRecognizeRequest(
recognizer=recognizer,
streaming_config=cloud_speech.StreamingRecognitionConfig(
config=recognition_config,
),
)
yield config_request
# b. Second, read the audio file and stream it in chunks.
with open(audio_file_path, "rb") as f:
audio_content = f.read()
for chunk in generate_audio_chunks(audio_content, CHUNK_SIZE):
yield cloud_speech.StreamingRecognizeRequest(audio=chunk)
responses = client.streaming_recognize(requests=create_streaming_requests(audio_file))
print("Streaming transcripts:")
all_transcripts = []
for response in responses:
for result in response.results:
transcript = result.alternatives[0].transcript
print(transcript)
all_transcripts.append(transcript)
final_transcript = " ".join(all_transcripts)
print(f"\n--- Final Combined Transcript ---\n{final_transcript}")