音声の理解

ai.google.dev で表示 Google Colab で実行 Kaggle で実行 Vertex AI で開く GitHub 上のソースを見る

Gemma 3n 以降では、音声プロンプトやワークフローで音声を直接使用できます。音声と話し言葉は、ユーザーの意図を把握し、身の回りの世界に関する情報を記録し、解決すべき特定の問題を理解するための豊富なデータソースです。

このガイドでは、Gemma 4 の音声処理機能(自動音声認識(ASR)、翻訳、一般的な音声理解など)の概要について説明します。

このノートブックは T4 GPU で実行されます。

Python パッケージをインストールする

Gemma モデルの実行とリクエストの作成に必要な Hugging Face ライブラリをインストールします。

# Install PyTorch & other libraries
pip install torch accelerate

# Install the transformers library
pip install "transformers>=5.10.1"

モデルを読み込む

次のコード例に示すように、transformers ライブラリを使用して、AutoProcessor クラスと AutoModelForImageTextToText クラスを使用して processormodel のインスタンスを作成します。

MODEL_ID = "google/gemma-4-E2B-it" # @param ["google/gemma-4-E2B-it","google/gemma-4-E4B-it", "google/gemma-4-12B-it"]

from transformers import pipeline

pipe = pipeline(
    task="any-to-any",
    model=MODEL_ID,
    device_map="auto",
    dtype="auto"
)
config.json:   0%|          | 0.00/4.95k [00:00<?, ?B/s]
model.safetensors:   0%|          | 0.00/10.2G [00:00<?, ?B/s]
Loading weights:   0%|          | 0/1951 [00:00<?, ?it/s]
generation_config.json:   0%|          | 0.00/208 [00:00<?, ?B/s]
processor_config.json:   0%|          | 0.00/1.69k [00:00<?, ?B/s]
chat_template.jinja:   0%|          | 0.00/17.3k [00:00<?, ?B/s]
tokenizer_config.json:   0%|          | 0.00/2.10k [00:00<?, ?B/s]
tokenizer.json:   0%|          | 0.00/32.2M [00:00<?, ?B/s]

音声データ

デジタル音声データには、さまざまな形式と解像度があります。Gemma で使用できる実際の音声形式(MP3 形式や WAV 形式など)は、音声データをテンソルに変換するために選択するフレームワークによって決まります。Gemma で処理する音声データを準備する際の具体的な考慮事項は次のとおりです。

  • トークン費用: 音声 1 秒あたり、Gemma 4 では 25 トークン(Gemma 3n では 6.25 トークン)。
  • クリップの長さ: 音声は最大 30 秒までサポートされます。
  • 音声チャンネル: 音声データは単一の音声チャンネルとして処理されます。左右のチャンネルなどのマルチチャンネル音声を使用している場合は、チャンネルを削除するか、音声データを単一のチャンネルに結合して、データを単一のチャンネルに減らすことを検討してください。
  • 技術的なエンコード:
    • サンプルレート: 16 kHz
    • ビット深度: 32 ビット浮動小数点形式。サンプルは [-1, 1] の範囲内で正規化されます。

処理する予定の音声データが入力処理と大きく異なる場合(特にチャンネル、サンプルレート、ビット深度に関して)、モデルで処理されるデータ解像度に合わせて音声データをリサンプリングまたはトリミングすることを検討してください。

音声エンコード

高レベルのライブラリ(Hugging Face AutoProcessor など)は音声の前処理を自動的に処理することが多いですが、カスタム エンコードを実装する必要がある場合もあります。

Gemma で使用する独自のコード実装で音声データをエンコードする場合は、推奨される変換プロセスに従う必要があります。MP3 や WAV エンコード データなど、特定の形式でエンコードされた音声ファイルを扱う場合は、まず ffmpeg などのライブラリを使用してサンプルにデコードする必要があります。データをデコードしたら、音声データを [-1, 1] の範囲のモノラル チャンネル、16 kHz の float32 波形に変換します。たとえば、44.1 kHz のステレオ符号付き 16 ビット PCM 整数 WAV ファイルを扱う場合は、次の手順を行います。

  • 音声データを 16 kHz に再サンプリングする
  • 2 つのチャンネルを平均化してステレオからモノラルにダウンミックス
  • int16 から float32 に変換し、32768.0 で割って [-1, 1] の範囲にスケーリングします。

音声入力

Gemma 4 E2B、E4B、12B Unified は多言語音声認識用にトレーニングされており、さまざまな言語の音声入力をテキストに変換できます。

音声認識(ASR)には、次のプロンプト構造を使用します。

Transcribe the following speech segment in {LANGUAGE} into {LANGUAGE} text.

Follow these specific instructions for formatting the answer:
*   Only output the transcription, with no newlines.
*   When transcribing numbers, write the digits, i.e. write 1.7 and not one point seven, and write 3 instead of three.

次のコード例は、Hugging Face Transformers を使用して音声ファイルからテキストを文字変換するようにモデルにプロンプトを送信する方法を示しています。

from transformers import GenerationConfig
config = GenerationConfig.from_pretrained(MODEL_ID)
config.max_new_tokens = 64
gen_kwargs = dict(generation_config=config)

RESOURCE_URL_PREFIX = "https://raw.githubusercontent.com/google-gemma/cookbook/refs/heads/main/apps/sample-data/"

messages = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": "Transcribe the following speech segment in its original language. Follow these specific instructions for formatting the answer:\n* Only output the transcription, with no newlines.\n* When transcribing numbers, write the digits, i.e. write 1.7 and not one point seven, and write 3 instead of three."},
            #{"type": "text", "text": "Transcribe the following speech segment in English into English text. Follow these specific instructions for formatting the answer:\n* Only output the transcription, with no newlines.\n* When transcribing numbers, write the digits, i.e. write 1.7 and not one point seven, and write 3 instead of three."},
            {"type": "audio", "audio": f"{RESOURCE_URL_PREFIX}journal1.wav"},
        ]
    }
]

outputs = pipe(messages, return_full_text=False, generate_kwargs=gen_kwargs)
print(outputs[0]['generated_text'])
I woke up early today feeling really fresh the morning light was beautiful and I enjoyed a nice cup of coffee<turn|>
from transformers import GenerationConfig
config = GenerationConfig.from_pretrained(MODEL_ID)
config.max_new_tokens = 1024
gen_kwargs = dict(generation_config=config)

messages = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": "Give me a concise overview of these audio files."},
            {"type": "text", "text": "journal1:"},
            {"type": "audio", "audio": f"{RESOURCE_URL_PREFIX}journal1.wav"},
            {"type": "text", "text": "journal2:"},
            {"type": "audio", "audio": f"{RESOURCE_URL_PREFIX}journal2.wav"},
            {"type": "text", "text": "journal3:"},
            {"type": "audio", "audio": f"{RESOURCE_URL_PREFIX}journal3.wav"},
            {"type": "text", "text": "journal4:"},
            {"type": "audio", "audio": f"{RESOURCE_URL_PREFIX}journal4.wav"},
            {"type": "text", "text": "journal5:"},
            {"type": "audio", "audio": f"{RESOURCE_URL_PREFIX}journal5.wav"},
        ]
    }
]

outputs = pipe(messages, return_full_text=False, generate_kwargs=gen_kwargs)
print(outputs[0]['generated_text'])
Here is a concise overview of each audio file:

**journal1:** The speaker describes a fresh and peaceful day, enjoying a cup of coffee.
**journal2:** The speaker had a perfect day at the park, including a walk and watching cherry blossoms.
**journal3:** The speaker finished the day with a good book, feeling grateful for simple moments.
**journal4:** The speaker returned from work and noted the beautiful night sky and a clear view from the train.
**journal5:** The speaker had a great lunch with an old friend, which was a pleasant way to catch up and made their day.
<turn|>

自動音声翻訳

Gemma 4 E2B、E4B、12B Unified は多言語音声翻訳タスク用にトレーニングされているため、音声音声を別の言語に直接翻訳できます。

自動音声翻訳(AST)には、次のプロンプト構造を使用します。

Transcribe the following speech segment in {SOURCE_LANGUAGE}, then translate it into {TARGET_LANGUAGE}.
When formatting the answer, first output the transcription in {SOURCE_LANGUAGE}, then one newline, then output the string '{TARGET_LANGUAGE}: ', then the translation in {TARGET_LANGUAGE}.

次のコード例は、Hugging Face Transformers を使用して、音声オーディオをテキストに変換するようにモデルにプロンプトする方法を示しています。

from transformers import GenerationConfig
config = GenerationConfig.from_pretrained(MODEL_ID)
config.max_new_tokens = 64
gen_kwargs = dict(generation_config=config)

messages = [
    {
        "role": "user",
        "content": [
            {"type": "text", "text": "Transcribe the following speech segment in English, then translate it into Korean. When formatting the answer, first output the transcription in English, then one newline, then output the string 'Korean: ', then the translation in Korean."},
            {"type": "audio", "audio": "https://ai.google.dev/gemma/docs/audio/roses-are.wav"},
        ]
    }
]

outputs = pipe(messages, return_full_text=False, generate_kwargs=gen_kwargs)
print(outputs[0]['generated_text'])
Roses are red, violets are blue.
Korean: 장미는 빨갛고, 제비꽃은 파랗다.<turn|>

自動音声翻訳 / 自動音声認識

自分で試してみる

pip install ipywebrtc

丸いボタンを押して話し始めます。話し終わったら、丸いボタンをもう一度クリックします。ウィジェットは、キャプチャした内容の再生をすぐに開始します。

from google.colab import output
output.enable_custom_widget_manager()

from ipywebrtc import AudioRecorder, CameraStream

camera = CameraStream(constraints={'audio': True,'video':False})
recorder = AudioRecorder(stream=camera)
recorder
AudioRecorder(audio=Audio(value=b'', format='webm'), stream=CameraStream(constraints={'audio': True, 'video': …

PyTorch が理解できる wav 形式に webm ファイルを変換します。

with open('/content/recording.webm', 'wb') as f:
    f.write(recorder.audio.value)
!ffmpeg -i /content/recording.webm /content/recording.wav -y
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
  configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Input #0, matroska,webm, from '/content/recording.webm':
  Metadata:
    encoder         : Chrome
  Duration: 00:00:03.00, start: 0.000000, bitrate: 132 kb/s
  Stream #0:0(eng): Audio: opus, 48000 Hz, mono, fltp (default)
Stream mapping:
  Stream #0:0 -> #0:0 (opus (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, wav, to '/content/recording.wav':
  Metadata:
    ISFT            : Lavf58.76.100
  Stream #0:0(eng): Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, mono, s16, 768 kb/s (default)
    Metadata:
      encoder         : Lavc58.134.100 pcm_s16le
size=     287kB time=00:00:02.99 bitrate= 783.7kbits/s speed=79.4x    
video:0kB audio:287kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.026552%

ASR

from transformers import GenerationConfig
config = GenerationConfig.from_pretrained(MODEL_ID)
config.max_new_tokens = 64
gen_kwargs = dict(generation_config=config)

messages = [{
  "role": "user",
  "content": [
    {"type": "text", "text": "Transcribe the following speech segment in its original language. Follow these specific instructions for formatting the answer:\n* Only output the transcription, with no newlines.\n* When transcribing numbers, write the digits, i.e. write 1.7 and not one point seven, and write 3 instead of three."},
    {"type": "audio", "audio": "/content/recording.wav"},
  ]
}]

outputs = pipe(messages, return_full_text=False, generate_kwargs=gen_kwargs)
print(outputs[0]['generated_text'])
How can I get to the station?<turn|>

AST

messages = [{
  "role": "user",
  "content": [
    {"type": "text", "text": "Transcribe the following speech segment in English, then translate it into Korean. When formatting the answer, first output the transcription in English, then one newline, then output the string 'Korean: ', then the translation in Korean."},
    {"type": "audio", "audio": "/content/recording.wav"},
  ]
}]

outputs = pipe(messages, return_full_text=False, generate_kwargs=gen_kwargs)
print(outputs[0]['generated_text'])
How can I get to the station?
Korean: 역에 어떻게 가나요?<turn|>

まとめと次のステップ

このガイドでは、Gemma 4 モデルを使用して音声を処理する方法について説明しました。例では、音声言語を文字変換する Speech-to-Text(ASR)と、音声音声を別の言語に直接翻訳する Automated Speech Translation(AST)を実行する方法を示しました。また、ノートブック環境でマイクから音声をキャプチャして処理する方法も説明しました。

詳しくは、以下のドキュメントをご覧ください。