Stop Wrestling with ASR: The Complete Guide to Gemini 3.5…
    Neura Market
    Neura Market
    /Stable Diffusion
    Marketplace
    Directories
    Resources
    Stable Diffusion
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityDeepSeekDeepSeekCoPilotCoPilotStable DiffusionStable DiffusionMidjourneyMidjourney
    OverviewPromptsBlogVideosGuidesCoursesCommunityModelsLoRAsComfyUI WorkflowsTrending
    Stable DiffusionBlogStop Wrestling with ASR: The Complete Guide to Gemini 3.5 Transcribe 🎙️
    Back to Blog
    Stop Wrestling with ASR: The Complete Guide to Gemini 3.5 Transcribe 🎙️
    ai

    Stop Wrestling with ASR: The Complete Guide to Gemini 3.5 Transcribe 🎙️

    Guillaume Vernade August 27, 2026
    0 views

    You’ve probably used Gemini to analyze hours of video, summarize podcasts, or answer questions from...

    You’ve probably used Gemini to analyze hours of video, summarize podcasts, or answer questions from recorded meetings (if you didn't you should, it's extremely useful!). But when all you need is a clean, hyper-accurate, and structured transcript from audio, spinning up a huge reasoning model with complicated prompts often feels like using a sledgehammer to crack a nut.

    Enter Gemini 3.5 Transcribe (gemini-3.5-transcribe).

    It's Google's dedicated speech-to-text model built on Gemini's audio understanding core, optimized specifically for fast, accurate, and cost-effective transcription. Whether you want an exact court-reporter transcript with millisecond timestamps, or a reading-optimized summary that removes all your awkward "ums" and "uhs", this model handles it natively with zero prompt gymnastics.

    🚀 Hands-on first: If you want to jump straight into running the code yourself, open the interactive Gemini Transcribe Colab notebook! It's ready to run so you can dirrectly experience how the model work.
    Prefer a visual UI with zero coding? You can also test speech recognition directly in Google AI Studio.


    Here's what you'll find in this guide:

      1. Why a Dedicated Transcription Model? (Audio Understanding vs. Transcribe)
      1. Setup & The Files API
      1. Steer Languages & Code-Switching (85+ Locales)
      1. Custom Vocabulary: Never Misspell Technical Jargon Again
      1. The Killer Feature: Smart Transcription vs. Verbatim Mode
      1. Speaker Diarization: Who Said What?
      1. Word-Level Timestamps: Precise Time Offsets for Every Spoken Word
      1. Decision Matrix: Which Configuration Should You Use?
      1. What About Real-Time Live Streaming?

    0. Why a Dedicated Transcription Model?

    Before looking at the code, let's get the mental model straight. You might wonder: "Can't I just upload an MP3 to Gemini 3.7 and say 'Transcribe this'?"

    You can, but here is why gemini-3.5-transcribe is different:

    FeatureGeneral Audio Understanding (e.g. Gemini 3.7)Dedicated Transcribe (gemini-3.5-transcribe)
    Primary JobReasoning, Q&A, sentiment analysis, audio chatHigh-throughput, precise speech-to-text
    Speaker DiarizationPrompt-dependent (can hallucinate turns)Native segment labeling (spk:0, spk:1)
    TimestampsApproximate timecodes via text promptTrue word-level millisecond offsets in metadata
    Vocabulary BiasingSystem prompt instructionsNative acoustic biasing dictionary (up to 1,000 terms)
    Cost & LatencyFull multimodal LLM generation overheadOptimized lightweight speech pipeline

    Pro tip: If you need to ask questions about what happened in an audio file ("What was the action item for Alice?"), use a multimodal model like Gemini 3.7. If you need the transcript itself, subtitles, or cleaned dictation notes, use Gemini Transcribe!


    1. Setup & The Files API

    The Gemini 3.5 Transcribe model runs on the modern Google GenAI SDK (google-genai v2.0+) using the Interactions API.

    First, install the SDK:

    pip install -U "google-genai>=2.0.0"
    

    Make sure you have an API key from Google AI Studio, set it as GEMINI_API_KEY, and let's look at how audio gets passed to the model:

    from google import genai
    
    client = genai.Client()
    
    # 1. Upload your audio file via the Files API
    audio_file = client.files.upload(file="meeting_recap.mp3")
    
    # 2. Request transcription using the uploaded file's URI
    interaction = client.interactions.create(
        model="gemini-3.5-transcribe",
        input=[{"type": "audio", "uri": audio_file.uri}],
    )
    
    print(interaction.output_text)
    

    Watch the demo video below to see the baseline transcription in action—handling natural speech and bilingual code-switching with ease:

    {% youtube I-leFQpz-j0 %}

    Why use the Files API?

    When dealing with audio and video, you never want to inline raw audio bytes as base64 in your API requests—it blows up the payload size by 33%, easily hits network timeouts, and requires re-uploading the same bytes if you want to rerun a query.

    The Files API solves this cleanly:

    • Large file support: Upload audio and video files up to 2 GB per file (with 20 GB of total project storage).
    • Temporary lifecycle: Files are stored for 48 hours and automatically cleaned up afterwards.
    • It's completely free! Storage and uploads in the Files API incur zero additional cost—you only pay for token processing when you actually run inference against the model.

    2. Steer Languages & Code-Switching (85+ Locales)

    As you saw in the video above, Gemini Transcribe automatically identifies spoken languages out of the box and seamlessly handles code-switching (when someone mixes multiple languages in the same sentence—like switching between French and English mid-sentence, which happens to me all the time!).

    However, if you know your audio is exclusively in a specific language or regional dialect, you can pass explicit BCP-47 language codes in transcription_config to bias recognition:

    interaction = client.interactions.create(
        model="gemini-3.5-transcribe",
        input=[{"type": "audio", "uri": spanish_audio.uri}],
        generation_config={
            "transcription_config": {
                # Explicit language hint
                "language_codes": ["es-ES"],
            }
        },
    )
    
    print(interaction.output_text)
    

    Note: Leaving language_codes=[] (or omitting it) enables full automatic detection across 85+ supported languages and locales. Check out the Audio Transcription Documentation for the complete list of language codes.


    3. Custom Vocabulary: Never Misspell Technical Jargon Again

    Every developer has suffered from an ASR model mangling proper names, confusing specialized libraries with everyday dictionary words (turning "ScaNN" into "scan", or "Qdrant" into "quadrant"), or inventing phonetically similar terms ("Sitsi" instead of "CitC", "Thiago" instead of "Tiago").

    With custom_vocabulary, you can pass a list of up to 1,000 domain-specific terms that the model will bias towards:

    interaction = client.interactions.create(
        model="gemini-3.5-transcribe",
        input=[{"type": "audio", "uri": team_briefing.uri}],
        generation_config={
            "transcription_config": {
                "custom_vocabulary": [
                    "Guillaume Vernade",
                    "ScaNN",
                    "Qdrant",
                    "Cilium",
                    "Weaviate",
                    "Milvus",
                    "Buganizer",
                    "Tiago",
                    "CitC",
                    "CL",
                    "spaCy",
                ],
            }
        },
    )
    
    print(interaction.output_text)
    

    Watch the side-by-side comparison video below to see how the model behaves with and without custom vocabulary biasing:

    {% youtube fsRINjkzDxw %}

    Without Custom Vocabulary (Default ASR)With custom_vocabulary (100% Precision)
    "For our vector benchmarks, sync with Guillaume Vernat in Paris to compare Scan against Quadrant while Syllium handles the traffic.""For our vector benchmarks, sync with Guillaume Vernade in Paris to compare ScaNN against Qdrant while Cilium handles the traffic."
    "We also need to evaluate Weaviate against Milvus, assign the buganizer ticket to Thiago, and test the changes in Sitsi before submitting the CL.""We also need to evaluate Weaviate against Milvus, assign the Buganizer ticket to Tiago, and test the changes in CitC before submitting the CL."
    "Finally, run a quick smoke test with Spacey to validate the tokenization pipeline before deploying.""Finally, run a quick smoke test with spaCy to validate the tokenization pipeline before deploying."

    Notice how default speech recognition falls back to phonetic dictionary guesses (Vernat, Scan, Quadrant, Syllium, Thiago, Sitsi, Spacey). By contrast, supplying custom_vocabulary guarantees that names of team members, niche tools, internal infrastructure, and open-source libraries are transcribed with 100% precision.

    Pro tip: Don't just put acronyms in your custom vocabulary. Add proper names of team members, internal service codenames, GitHub repo handles, product brand names, and niche industry terminology.


    4. The Killer Feature: Smart Transcription vs. Verbatim Mode

    This is hands down my favorite capability of Gemini 3.5 Transcribe.

    By default, speech-to-text models operate in verbatim mode: they write down everything, including every nervous stutter, throat clear, false start, and verbal tick.

    When you're transcribing a speech rehearsal, interview, or voice memo, reading raw verbatim text is painful:

    --- Verbatim output ---
    "Uh, hello. Good evening, everyone. Um, I'd like to start by, well, first of all, thank you all for coming. Today is, um, a very special day, or rather, evening? No, afternoon? Right, evening. We are here to celebrate, uh, sorry, let me just find my notes. Ah, here. We are here to honor, no, not honor, but, um, to mark the launch of our new, sorry, my glasses are a bit foggy, the new marketing campaign. No, wait, product campaign? Product, yes. Um, where was I? Ah, yes. It has been a long journey, a very, uh, challenging, well, not challenging in a bad way, but, you know, difficult? No, rewarding. Rewarding is the word. So, um, yes, cheers to, wait, we don't have glasses yet. Thank you."
    

    If you switch mode={"type": "smart"}, the model performs intelligent reading optimization:

    1. Disfluency removal: Strips conversational filler words ("um", "uh", "you know").
    2. Inline self-corrections: Automatically resolves verbal slip-ups ("Tuesday, wait no, Wednesday" $\rightarrow$ "Wednesday").
    3. Structured formatting: Formats lists, bullet points, numbers, currencies ($26M), and natural paragraphs.

    Here is how you turn it on:

    interaction_smart = client.interactions.create(
        model="gemini-3.5-transcribe",
        input=[{"type": "audio", "uri": audio_file.uri}],
        generation_config={
            "transcription_config": {
                "mode": {
                    "type": "smart",
                },
            }
        },
    )
    
    print(interaction_smart.output_text)
    

    Look at the cleaned result on that exact same rehearsal audio:

    --- Smart transcription output ---
    Good evening everyone. First of all, thank you all for coming. Today is a very special evening. We are here to mark the launch of our new product campaign.
    
    It has been a long journey, a very rewarding one. So, cheers to that.
    

    Watch the side-by-side comparison video below to see how the raw disfluencies are stripped while listening:

    {% youtube I-leFQpz-j0 %}

    (If the video doesn't load, you can listen to rehearsing.wav directly.)

    Important caveat: Because Smart transcription uses language modeling to clean up disfluencies and structure the output, it might slightly rewrite, omit, or rephrase parts of what was said to make it sound natural and concise. If you are doing verbatim court reporting, medical transcription, or subtitle syncing where every exact syllable matters, stick with verbatim mode!

    Also note that Smart mode is incompatible with word-level timestamps and speaker diarization (which require {"type": "verbatim"}).


    5. Speaker Diarization: Who Said What?

    Need to know who spoke during a multi-person meeting or podcast? Enable diarization with diarization_mode="speaker":

    interaction = client.interactions.create(
        model="gemini-3.5-transcribe",
        input=[{"type": "audio", "uri": meeting_audio.uri}],
        generation_config={
            "transcription_config": {
                "mode": {
                    "type": "verbatim",
                    "diarization_mode": "speaker",
                },
            }
        },
    )
    

    To extract each speaker turn cleanly, iterate through the step annotations:

    def print_diarized_transcript(interaction):
      words = []
      for step in getattr(interaction, "steps", []) or []:
        for content in getattr(step, "content", []) or []:
          for annotation in getattr(content, "annotations", []) or []:
            if getattr(annotation, "type", None) == "word_info":
              words.append(annotation)
    
      current_speaker = None
      current_turn = []
    
      for w in words:
        speaker = getattr(w, "speaker", "spk:0")
        if speaker != current_speaker:
          if current_turn:
            print(f"[{current_speaker}]: {' '.join(current_turn)}")
          current_speaker = speaker
          current_turn = [w.text]
        else:
          current_turn.append(w.text)
    
      if current_turn:
        print(f"[{current_speaker}]: {' '.join(current_turn)}")
    
    
    print_diarized_transcript(interaction)
    

    Output:

    [spk:0]: One chocolatine, please.
    [spk:1]: Tiago, arrête. It is a pain au chocolat.
    [spk:0]: Wait, a guy from the south west told me it's chocolatine.
    [spk:1]: Do not listen to them. 90% of France and the entire universe calls it pain au chocolat. Chocolatine is a myth.
    [spk:0]: Meu Deus, you French are intense. In Brazil, people fight the exact same way over bolacha versus biscoito.
    [spk:1]: Well, here pain au chocolat is the only real word.
    [spk:0]: Fine. Two pain au chocolat, please. As long as it has chocolate, tá valendo.
    

    Watch the demo video below where two colleagues debate pain au chocolat vs. chocolatine. Notice how the waveform line dynamically changes color (Cyan for Tiago, Orange for his colleague) as each speaker takes turns:

    {% youtube mdvDSB3c4kg %}

    (Direct audio link: listen to pain_au_chocolat.wav)


    6. Word-Level Timestamps: Precise Time Offsets for Every Spoken Word

    When you need exact synchronization—for example, to jump to specific points in a video, build interactive transcripts, or align text with waveforms—you can request word-level millisecond start and end offsets.

    Configure timestamp_granularities=["word"] (and optionally combine it with diarization_mode="speaker"):

    interaction = client.interactions.create(
        model="gemini-3.5-transcribe",
        input=[{"type": "audio", "uri": audio_file.uri}],
        generation_config={
            "transcription_config": {
                "mode": {
                    "type": "verbatim",
                    "timestamp_granularities": ["word"],
                    "diarization_mode": "speaker",
                },
            }
        },
    )
    

    Each recognized word comes back with its exact time offsets (and speaker turn) attached in the content annotations:

    words = []
    for step in getattr(interaction, "steps", []) or []:
      for content in getattr(step, "content", []) or []:
        for annotation in getattr(content, "annotations", []) or []:
          if getattr(annotation, "type", None) == "word_info":
            words.append(annotation)
    
    for w in words[:6]:
      spk = getattr(w, "speaker", "spk:0")
      print(f"[{w.start_offset:>7} -> {w.end_offset:>7}] ({spk}) {w.text}")
    

    Output:

    [ 0.000s ->  0.400s] (spk:0) One
    [ 0.400s ->  1.200s] (spk:0) chocolatine,
    [ 1.200s ->  1.800s] (spk:0) please.
    [ 3.200s ->  3.700s] (spk:1) Tiago,
    [ 3.700s ->  4.200s] (spk:1) arrête.
    [ 4.200s ->  4.500s] (spk:1) It
    
    What can you do with word timestamps?

    Having millisecond-level offsets for every individual word unlocks huge capabilities:

    • Instant subtitles (.srt / .ass): Group words into 3-5 second caption blocks for YouTube, Premiere, or Final Cut.
    • Karaoke & dynamic captions: Highlight each word in real-time as it's spoken (like TikTok / YouTube Shorts).
    • Click-to-play search: Build audio/video search indexes where clicking any search keyword immediately seeks the player to that exact millisecond.
    • Waveform & visual animations: Trigger visual events or highlight specific spoken phrases on screen.

    💡 Behind the scenes: That's actually what I did to make the demo videos above! The word timestamps provided the exact millisecond timing to align the subtitle cards, highlight the custom terms ("oatmilk"), and trigger the color switch of the waveform line from Cyan to Orange when the speaker changed.

    If you want the complete Python function to convert these word annotations into standard .srt subtitle files, you can find it directly in the interactive Cookbook Colab notebook.


    7. Decision Matrix: Which Configuration Should You Use?

    Here is a quick cheat sheet to pick the right settings for your use case:

    Use CaseModeDiarizationTimestampsCustom Vocab
    Meeting Notes / Voice MemossmartNoNoOptional
    Video Subtitles / Closed CaptionsverbatimOptional["word"]Highly recommended
    Podcast / Multi-speaker Interviewverbatimspeaker["word"]Highly recommended
    Legal / Compliance Audio Logsverbatimspeaker["word"]Optional
    Search Indexing & EmbeddingssmartNoNoOptional

    8. What About Real-Time Live Streaming?

    Everything we covered above is for pre-recorded audio files (unary mode via the Files API).

    Gemini also supports real-time live streaming transcription over WebSockets using gemini-3.5-transcribe-live and the Live API. It lets you stream raw 16-bit PCM chunks (100ms each) directly from a microphone and receive instantaneous interim partial hypotheses (interim_input_transcription) and finalized text as speech occurs.

    However, streaming real-time WebSockets with asynchronous Python workers (asyncio), handling audio chunking, and managing ephemeral valet tokens for secure client apps is quite a bit more complex and deserves its own dedicated tutorial.

    If you want to dive straight into live streaming code right now:

    • 📖 Open the Gemini Transcribe Colab Notebook (it includes runnable cells for live streaming and ephemeral token creation!)
    • 📚 Read the official Gemini Live Transcription Documentation on ai.google.dev.

    Wrapping Up

    Gemini 3.5 Transcribe gives you the best of both worlds: strict, millisecond-accurate verbatim data when you need timestamps and diarization, and an intelligent, disfluency-stripping smart mode when you want clean text for human eyes.

    Have you tried using smart mode on your own voice recordings or meetings? Drop your thoughts and edge cases in the comments below! 🚀🚀🚀

    Tags

    aistttutorial

    Comments

    More Blog

    View all
    Overcoming Dart's Single Inheritance Wall: Composable CubitSignalMixin & BlocSignalMixin in Flutterflutter

    Overcoming Dart's Single Inheritance Wall: Composable CubitSignalMixin & BlocSignalMixin in Flutter

    Discover how CubitSignalMixin and BlocSignalMixin allow any existing Flutter controller, domain repository, or enterprise class to gain full reactive state container capabilities without occupying its single inheritance slot.

    R
    Randal L. Schwartz
    Taking Advantage of Gemini Managed Agents with Google Apps Scriptgoogleappsscript

    Taking Advantage of Gemini Managed Agents with Google Apps Script

    Breaking the Limits of GAS with Direct Cloud-to-Cloud Streaming in Persistent Linux...

    T
    Tanaike
    Grand Central Station: Why BLoC, Riverpod, and BlocSignal Are Now True Peersflutter

    Grand Central Station: Why BLoC, Riverpod, and BlocSignal Are Now True Peers

    Discover why Flutter state management is no longer an all-or-nothing choice. Explore how BlocSignal, Classic BLoC, and Riverpod now operate as first-class bidirectional peers at the Grand Central State Terminal.

    R
    Randal L. Schwartz
    Unlocking workload rightsizing visibility on GKE: How VPA decision logs bring observability to autoscalingkubernetes

    Unlocking workload rightsizing visibility on GKE: How VPA decision logs bring observability to autoscaling

    Learn how to troubleshoot and audit GKE Vertical Pod Autoscaler actions with structured decision logs in Cloud Logging.

    O
    Olivier Bourgeois
    Accelerating JVM startup on GKE: How VPA CPU startup boost eliminates ongoing resource wastekubernetes

    Accelerating JVM startup on GKE: How VPA CPU startup boost eliminates ongoing resource waste

    Learn how GKE VerticalPodAutoscaler (VPA) CPU Startup Boost cuts JVM cold starts and eliminates ongoing CPU waste using in-place Pod resizing.

    O
    Olivier Bourgeois
    Why AI Websites All Look the Same and How to Build Something Differentai

    Why AI Websites All Look the Same and How to Build Something Different

    If you've built a website with AI recently, there is a good chance it looks familiar. Maybe you have...

    M
    Mfonobong Umondia

    Stay up to date

    Get the latest Stable Diffusion prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for Stable Diffusion and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Guides

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.

    Neura Market

    Custom AI Systems & Services

    Our team of experienced AI builders will help build custom AI systems, workflows, and solutions.

    Request custom work

    Ready-made automations for this

    Workflows from the Neura Market marketplace related to this Stable Diffusion resource

    • AI-Powered Auto-Generated Exam Questions and Answers from Google Docs with Geminin8n · $24.99 · Related topic
    • Answer Questions from Documents with RAG Using Supabase, OpenAI, & Cohere Rerankern8n · $14.99 · Related topic
    • Query and Answer Questions from Excel Spreadsheets with GPT-4 Minin8n · $9.99 · Related topic
    • Transcribe and Analyze Sentiment of Audio Files from Google Drive with Eden AImake · $4.99 · Related topic
    Browse all workflows