Skip to content

Streaming for ASR - #79

Closed
BrandonWeng wants to merge 22 commits into
mainfrom
asr-streaming
Closed

Streaming for ASR #79
BrandonWeng wants to merge 22 commits into
mainfrom
asr-streaming

Conversation

@BrandonWeng

@BrandonWeng BrandonWeng commented Aug 26, 2025

Copy link
Copy Markdown
Member

Why is this change needed?

Adding support for ASR streaming. Majority of the change is in Sources/FluidAudio/ASR/Streaming/StreamingAsrManager.swift

e.g swift run fluidaudio transcribe GLM\ 4.5.wav --streaming

Clipboard-20250826-052557-193.mp4
stt.mp4

@BrandonWeng BrandonWeng added documentation Improvements or additions to documentation enhancement New feature or request labels Aug 26, 2025

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comprehensive code review completed. This PR significantly improves FluidAudio's streaming ASR capabilities with excellent API design and examples.

Key Strengths:

  • Dual-stream architecture (results vs snapshots) elegantly separates detailed events from UI updates
  • Production-quality SwiftUI and UIKit examples with proper patterns
  • Well-tuned .realtime configuration for responsive transcription

Critical Issue to Address:

  • Memory leak risk: finalizedSegments and segmentFinalTexts collections grow unbounded during long sessions (could accumulate thousands of segments in memory)

Recommendations:

  • Implement segment cleanup mechanism for long-running sessions
  • Consider structured concurrency patterns in audio callback examples
  • Add migration guide for API changes

Overall, this is a solid architectural improvement that addresses real-world streaming ASR needs effectively. The memory management issue should be resolved before merge.

@github-actions

github-actions Bot commented Aug 26, 2025

Copy link
Copy Markdown

Speaker Diarization Benchmark Results

Speaker Diarization Performance

Evaluating "who spoke when" detection accuracy

Metric Value Target Status Description
DER 15.1% <30% Diarization Error Rate (lower is better)
JER 24.9% <25% Jaccard Error Rate
RTFx 19.64x >1.0x Real-Time Factor (higher is faster)

Diarization Pipeline Timing Breakdown

Time spent in each stage of speaker diarization

Stage Time (s) % Description
Model Download 8.953 16.8 Fetching diarization models
Model Compile 3.837 7.2 CoreML compilation
Audio Load 0.090 0.2 Loading audio file
Segmentation 16.011 30.0 Detecting speech regions
Embedding 26.685 50.0 Extracting speaker voices
Clustering 10.674 20.0 Grouping same speakers
Total 53.421 100 Full pipeline

Speaker Diarization Research Comparison

Research baselines typically achieve 18-30% DER on standard datasets

Method DER Notes
FluidAudio 15.1% On-device CoreML
Research baseline 18-30% Standard dataset performance

Note: RTFx shown above is from GitHub Actions runner. On Apple Silicon with ANE:

  • M2 MacBook Air (2022): Runs at 150 RTFx real-time
  • Performance scales with Apple Neural Engine capabilities

🎯 Speaker Diarization Test • AMI Corpus ES2004a • 1049.0s meeting audio • 53.4s diarization time • Test runtime: 1m 35s • 09/08/2025, 11:58 PM EST

@github-actions

github-actions Bot commented Aug 26, 2025

Copy link
Copy Markdown

ASR Benchmark Results ✅

Status: All benchmarks passed

Dataset WER Avg WER Med RTFx Status
test-clean 0.57% 0.00% 3.05x
test-other 1.19% 0.00% 2.03x

🚀 Streaming Performance Test

Metric Value Status Description
WER 0.00% Word Error Rate in streaming mode
RTFx 0.37x Streaming real-time factor
Avg Chunk Time 2.396s Average time to process each chunk
Max Chunk Time 2.967s Maximum chunk processing time
First Token 2.726s Latency to first transcription token
Total Chunks 31 Number of chunks processed

Streaming test validates --streaming option with 5 files using 0.5s chunks to simulate real-time audio streaming

25 files per dataset • Test runtime: 3m41s • 09/09/2025, 12:01 AM EST

RTFx = Real-Time Factor (higher is better) • Calculated as: Total audio duration ÷ Total processing time
Processing time includes: Model inference on Apple Neural Engine, audio preprocessing, state resets between files, token-to-text conversion, and file I/O
Example: RTFx of 2.0x means 10 seconds of audio processed in 5 seconds (2x faster than real-time)

Expected RTFx Performance on Physical M1 Hardware:

• M1 Mac: ~28x (clean), ~25x (other)
• CI shows ~0.5-3x due to virtualization limitations

Testing methodology follows HuggingFace Open ASR Leaderboard

@github-actions

github-actions Bot commented Aug 26, 2025

Copy link
Copy Markdown

VAD Benchmark Results

Performance Comparison

Dataset Accuracy Precision Recall F1-Score RTFx Files
MUSAN 88.0% 80.6% 100.0% 89.3% 84.3x faster 50
VOiCES 88.0% 80.6% 100.0% 89.3% 82.3x faster 50

Dataset Details

  • MUSAN: Music, Speech, and Noise dataset - standard VAD evaluation
  • VOiCES: Voices Obscured in Complex Environmental Settings - tests robustness in real-world conditions

✅: Average F1-Score above 70%

@BrandonWeng
BrandonWeng force-pushed the asr-streaming branch 2 times, most recently from 72a877b to 260e7f3 Compare August 26, 2025 19:59
@FluidInference FluidInference deleted a comment from claude Bot Aug 26, 2025
@BrandonWeng

Copy link
Copy Markdown
Member Author

@claude review the whole PR

Comment thread README.md Outdated
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/FluidInference/FluidAudio)


Fluid Audio is a Swift framework for fully local, low-latency audio processing on Apple devices. It provides state-of-the-art speaker diarization, ASR, and voice activity detection through open-source models (MIT/Apache 2.0 licensed) that we've converted to Core ML.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@claude double check the readme for me

@claude claude Bot Aug 27, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude finished @BrandonWeng's task —— View job


README.md Review Complete ✅

I've thoroughly reviewed the updated README.md and cross-referenced it with the actual implementation. The documentation is accurate and well-written, with only one minor typo to fix:


Issues Found

Line 27: Typo

- **Cross-platform**: Support for macOS 14.0+ and iOS 17.0+ and Apple Sillicon device
+ **Cross-platform**: Support for macOS 14.0+ and iOS 17.0+ and Apple Silicon device

(Note: "Sillicon" should be "Silicon")


What I Verified ✅

  1. Streaming API Examples: All code examples match the actual StreamingAsrManager implementation
  2. Configuration Options: The StreamingAsrConfig.realtime and .default presets exist exactly as documented
  3. CLI Commands: The --streaming flag and commands are implemented correctly
  4. Performance Numbers: RTFx and benchmarking data aligns with CI results
  5. API Consistency: Both single-stream and multi-stream examples are accurate
  6. Parameter Documentation: All config parameters like chunkSeconds, leftContextSeconds, etc. match the implementation

Strengths

  • Comprehensive Coverage: Excellent documentation of both batch and streaming modes
  • Practical Examples: Real-world usage patterns with proper async/await syntax
  • Performance Context: Clear RTFx explanations and hardware-specific expectations
  • Configuration Guidance: Well-explained parameter impacts on latency vs accuracy

The streaming ASR documentation is production-ready and accurately reflects the implementation. Just fix the "Sillicon" typo and it's perfect.

Comment thread .github/workflows/tests.yml Outdated
Comment on lines -26 to -32
- name: Cache iOS Platform
uses: actions/cache@v4
with:
path: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform
key: ios-platform-${{ runner.os }}-xcode-${{ hashFiles('/Applications/Xcode.app/Contents/version.plist') }}
restore-keys: |
ios-platform-${{ runner.os }}-xcode-

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a huge file so easier to redownload, notice that hte cahce doesn't work all the time anyways

Comment thread docs/wwdc2025-asr.txt Outdated
@@ -1,441 +0,0 @@
Hello! I’m Donovan, an engineer on the Speech framework team and I’m Shantini, an engineer on the Notes team.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not very useful for us here

Comment thread README.md
[![Platform](https://img.shields.io/badge/Platform-macOS%20%7C%20iOS-blue.svg)](https://developer.apple.com)
[![Discord](https://img.shields.io/badge/Discord-Join%20Chat-7289da.svg)](https://discord.gg/WNsvaCtmDe)
[![Models](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Model-blue)](https://huggingface.co/collections/FluidInference/coreml-models-6873d9e310e638c66d22fba9)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/FluidInference/FluidAudio)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved around the sections a bit and cleanedu p the phrases as well

@BrandonWeng
BrandonWeng marked this pull request as ready for review August 27, 2025 02:47
@FluidInference FluidInference deleted a comment from claude Bot Aug 27, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Artificial delay when streaming or else its too fast, and you can't even see it

Comment thread Sources/FluidAudioCLI/Commands/TranscribeCommand.swift Outdated
Comment thread Sources/FluidAudio/ASR/Streaming/StreamingAsrManager.swift Outdated
Comment thread Sources/FluidAudio/ASR/Streaming/StreamingAsrManager.swift Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this all from the parakeet python code

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, parakeet python code's streaming implementation requires a bit too much time, its not responsive enough. Takes inspiration from it and the apple streaming API

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is the apple streaming api doc from

Comment thread Sources/FluidAudioCLI/Commands/MultiStreamCommand.swift Outdated
Comment thread Sources/FluidAudioCLI/StreamingUI.swift Outdated
Comment thread Sources/FluidAudioCLI/StreamingUI.swift Outdated
Comment thread Sources/FluidAudio/ASR/Streaming/StreamingAsrManager.swift Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this gonna be frequent ? removeFirst is like O(n)

Comment thread Sources/FluidAudio/ASR/Streaming/StreamingAsrManager.swift Outdated
Comment thread Sources/FluidAudio/ASR/Streaming/StreamingAsrManager.swift Outdated
@Alex-Wengg

Copy link
Copy Markdown
Member

i gues we will watch out for deadlocks , race conditions and possible memory leaks. the keep priority code being asrmanager.swift

@BrandonWeng
BrandonWeng force-pushed the asr-streaming branch 2 times, most recently from 2abad6e to eb93191 Compare August 27, 2025 05:06
The Cross-Platform Build Check was failing on main branch pushes due to a race condition where iOS simulators were listed as available but not yet accessible to xcodebuild.

Changes:
- Add xcodebuild verification step with 5-attempt retry mechanism
- Wait for simulator to be fully available before build attempts
- Add diagnostic output showing available destinations
- Implement UUID-based fallback as final attempt
- Improve error messages and debugging information

This eliminates the timing issue causing "Unable to find a device matching the provided destination specifier" errors.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread Sources/FluidAudio/ASR/Streaming/StreamingTranscriptionResult.swift Outdated
Comment thread Sources/FluidAudio/ASR/Streaming/StreamingTranscriptionResult.swift Outdated
@Alex-Wengg

Copy link
Copy Markdown
Member

are the streaming prefixes necessary for the streaming asr files ?

@BrandonWeng

Copy link
Copy Markdown
Member Author

are the streaming prefixes necessary for the streaming asr files ?

Lets keep it, or else hard to know which is which.

@ozansz

ozansz commented Aug 28, 2025

Copy link
Copy Markdown

stt.mp4

Hi, is the code running in this demo video listening to the speakers of your device or did you somehow duplicated the sound output to a virtual device and redirected it to the running streaming ASR? I'm asking because I'm currently trying to find easy-to-implement native ways to do so.

@BrandonWeng

Copy link
Copy Markdown
Member Author

e.g swift run fluidaudio transcribe GLM\ 4.5.wav --streaming

Oh no, in this case it was just listening to the microphone, swift run fluidaudio transcribe --microphone. You should be able to use CoreAudio to tap into the system audio if that's what you're looking for

@BrandonWeng BrandonWeng added the speech-to-text issues related to transcription/asr label Sep 8, 2025
@benbjurstrom

Copy link
Copy Markdown

Thanks for the awesome package, it's been great to work with so far. I know this feature isn't final yet, but just wanted to share some issues I'm seeing.

The screenshot below is a csv dump of streamingAsr.segmentUpdates taken from playing this video into my microphone: https://www.youtube.com/watch?v=s0EbxhQYeCA

If you look at lines 33 and 34, as the segment moves from volatile to stable a bunch of the segment text is lost. I see this often when using the .balanced profile.

Screenshot 2025-09-17 at 7 43 14 AM

There's also other weirdness between volatile and stable updates. Seems to happen most often around the boundaries of chunkDuration. For example, volatile line 17 ends in "But", but it's removed from the stable line 18, and only appears again at the beginning of the next stable update on line 24.

@BrandonWeng

Copy link
Copy Markdown
Member Author

Thanks for the awesome package, it's been great to work with so far. I know this feature isn't final yet, but just wanted to share some issues I'm seeing.

The screenshot below is a csv dump of streamingAsr.segmentUpdates taken from playing this video into my microphone: https://www.youtube.com/watch?v=s0EbxhQYeCA

If you look at lines 33 and 34, as the segment moves from volatile to stable a bunch of the segment text is lost. I see this often when using the .balanced profile.

Screenshot 2025-09-17 at 7 43 14 AM There's also other weirdness between volatile and stable updates. Seems to happen most often around the boundaries of chunkDuration. For example, volatile line 17 ends in "But", but it's removed from the stable line 18, and only appears again at the beginning of the next stable update on line 24.

Thanks a bunch for the feedback @benbjurstrom - I've been distracted with the VAD model improvements. Hoping to revisit streaming ASR next week 🙏

@BrandonWeng

Copy link
Copy Markdown
Member Author

Going to close this for now, drifted too far from main and haven't been able to find time to work on this

@chinarui-na

chinarui-na commented Feb 25, 2026

Copy link
Copy Markdown

Why is this change needed?

Adding support for ASR streaming. Majority of the change is in Sources/FluidAudio/ASR/Streaming/StreamingAsrManager.swift

e.g swift run fluidaudio transcribe GLM\ 4.5.wav --streaming

Clipboard-20250826-052557-193.mp4
stt.mp4

Are there any examples to demo the stt.mp4 example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request speech-to-text issues related to transcription/asr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants