הבנת אודיו

לצפייה באתר ai.google.dev הפעלה ב-Google Colab הפעלה ב-Kaggle פתיחה ב-Vertex AI צפייה במקור ב-GitHub

החל מ-Gemma 3n, אתם יכולים להשתמש באודיו ישירות בהנחיות ובזרימות העבודה. אודיו ושפה מדוברת הם מקורות עשירים של נתונים לזיהוי כוונות המשתמש, לתיעוד מידע על העולם שסביבנו ולהבנה של בעיות ספציפיות שצריך לפתור.

במדריך הזה מוסבר על היכולות של Gemma 4 בעיבוד אודיו, כולל זיהוי דיבור אוטומטי (ASR), תרגום והבנה כללית של דיבור.

ה-notebook הזה יפעל ב-GPU מסוג T4.

התקנת חבילות Python

מתקינים את הספריות של Hugging Face שנדרשות להרצת מודל Gemma ולשליחת בקשות.

# Install PyTorch & other libraries
pip install torch accelerate

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

טעינת מודל

משתמשים בספריות transformers כדי ליצור מופע של processor ושל model באמצעות המחלקות AutoProcessor ו-AutoModelForImageTextToText, כמו בדוגמת הקוד הבאה:

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:

  • עלות הטוקנים: כל שנייה של אודיו היא 25 טוקנים ב-Gemma 4‏ (6.25 טוקנים ב-Gemma 3n).
  • אורך הקליפ: האורך המקסימלי של קליפ אודיו הוא 30 שניות.
  • ערוצי אודיו: נתוני האודיו מעובדים כערוץ אודיו יחיד. אם אתם משתמשים באודיו רב-ערוצי, כמו ערוצים שמאלי וימני, כדאי לצמצם את הנתונים לערוץ יחיד על ידי הסרת ערוצים או שילוב נתוני האודיו לערוץ יחיד.
  • קידוד טכני:
    • תדירות דגימה: 16kHz
    • עומק סיביות: פורמט מספר ממשי (float) ב-32 ביט, עם דגימות מנורמלות בטווח [‎-1, 1].

אם נתוני האודיו שאתם מתכננים לעבד שונים באופן משמעותי מהעיבוד של נתוני הקלט, במיוחד מבחינת ערוצים, תדירות דגימה ועומק סיביות, כדאי לשקול דגימה מחדש או חיתוך של נתוני האודיו כדי להתאים לרזולוציית הנתונים שהמודל מטפל בה.

קידוד אודיו

ספריות ברמה גבוהה (כמו Hugging Face AutoProcessor) מטפלות בדרך כלל בעיבוד מקדים של אודיו באופן אוטומטי, אבל לפעמים צריך להטמיע קידוד בהתאמה אישית.

כשמקודדים נתוני אודיו באמצעות הטמעה של קוד משלכם לשימוש עם Gemma, צריך לפעול לפי תהליך ההמרה המומלץ. אם אתם עובדים עם קובצי אודיו שמקודדים בפורמט ספציפי, כמו נתוני MP3 או WAV מקודדים, אתם צריכים קודם לפענח אותם לדגימות באמצעות ספרייה כמו ffmpeg. אחרי פענוח הנתונים, צריך להמיר את האודיו לצורות גל של float32 בטווח [‎-1, 1] עם ערוץ מונו בתדר 16kHz. לדוגמה, אם אתם עובדים עם קובצי WAV של מספרים שלמים בפורמט PCM חתום של 16 ביט בסטריאו בתדר 44.1kHz, אתם צריכים לפעול לפי השלבים הבאים:

  • דגימה מחדש של נתוני האודיו ל-16kHz
  • דאון-מיקס מסטריאו למונו על ידי חישוב ממוצע של 2 הערוצים
  • המרת הערך מ-int16 ל-float32, וחלוקה ב-32768.0 כדי לשנות את קנה המידה לטווח [‎-1, 1]

המרת דיבור לטקסט (STT)

מודלי 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': …

ממירים קובץ webm לפורמט wav ש-PyTorch יכול להבין.

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. בדוגמאות הראינו איך לבצע המרת דיבור לטקסט (ASR) כדי לתמלל שפה מדוברת, וגם איך לבצע תרגום אוטומטי של דיבור (AST) כדי לתרגם אודיו מדובר ישירות לשפה אחרת. ראיתם גם איך להקליט אודיו ממיקרופון בסביבת מחברת לעיבוד.

מידע נוסף זמין במאמרי העזרה הבאים.