-
Notifications
You must be signed in to change notification settings - Fork 504
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: make screenpipe-audio 100% based on tokio tasks instead of …
…a mess of OS thread + async. also remove dead code, and add benchmarks
- Loading branch information
1 parent
ee26658
commit 3e3d2a3
Showing
23 changed files
with
629 additions
and
31,242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# act -W .github/workflows/benchmark.yml --container-architecture linux/amd64 -j benchmark -P ubuntu-latest=catthehacker/ubuntu:act-latest | ||
|
||
name: Rust Benchmark | ||
|
||
on: [push] | ||
|
||
env: | ||
CARGO_TERM_COLOR: always | ||
|
||
jobs: | ||
benchmark: | ||
name: Run Rust benchmark | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: dtolnay/rust-toolchain@stable | ||
|
||
- name: Install dependencies | ||
run: | | ||
sudo apt-get update | ||
sudo apt-get install -y libavformat-dev libavfilter-dev libavdevice-dev ffmpeg libasound2-dev | ||
- name: Run benchmark | ||
run: | | ||
cargo bench --bench pcm_decode_benchmark stt_benchmark -- --output-format bencher | tee output.txt | ||
echo "Benchmark output:" | ||
cat output.txt | ||
- name: Store benchmark result | ||
uses: benchmark-action/github-action-benchmark@v1 | ||
with: | ||
name: Rust Benchmark | ||
tool: "cargo" | ||
output-file-path: output.txt | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
auto-push: false # TODO: https://github.com/benchmark-action/github-action-benchmark/tree/master?tab=readme-ov-file#charts-on-github-pages-1 | ||
# Show alert with commit comment on detecting possible performance regression | ||
alert-threshold: "200%" | ||
comment-on-alert: true | ||
fail-on-alert: true | ||
alert-comment-cc-users: "@louis030195" | ||
|
||
- name: Upload benchmark results | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: benchmark-results | ||
path: output.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// cargo bench --bench audio_benchmark | ||
|
||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
use screenpipe_audio::{create_whisper_channel, stt, AudioInput, WhisperModel}; | ||
use std::time::{Duration, Instant}; | ||
use tokio::runtime::Runtime; | ||
|
||
fn generate_large_audio_file(path: &str, duration_secs: u32) { | ||
use std::process::Command; | ||
|
||
Command::new("ffmpeg") | ||
.args(&[ | ||
"-f", | ||
"lavfi", | ||
"-i", | ||
&format!("sine=frequency=1000:duration={}", duration_secs), | ||
"-acodec", | ||
"pcm_s16le", | ||
"-ar", | ||
"44100", | ||
path, | ||
]) | ||
.output() | ||
.expect("Failed to generate audio file"); | ||
} | ||
|
||
fn benchmark_stt(c: &mut Criterion) { | ||
let whisper_model = WhisperModel::new().unwrap(); | ||
let test_file = "test_audio.wav"; | ||
generate_large_audio_file(test_file, 60); // 1-minute audio file | ||
|
||
c.bench_function("stt_1min_audio", |b| { | ||
b.iter(|| { | ||
let start = Instant::now(); | ||
let result = stt(black_box(test_file), black_box(&whisper_model)); | ||
let stt_duration = start.elapsed(); | ||
println!("STT duration: {:?}", stt_duration); | ||
result.unwrap(); | ||
}) | ||
}); | ||
|
||
std::fs::remove_file(test_file).unwrap(); | ||
} | ||
|
||
fn benchmark_concurrent_stt(c: &mut Criterion) { | ||
let runtime = Runtime::new().unwrap(); | ||
let test_files: Vec<String> = (0..10).map(|i| format!("test_audio_{}.wav", i)).collect(); | ||
|
||
for file in &test_files { | ||
generate_large_audio_file(file, 30); // 30-second audio files | ||
} | ||
|
||
c.bench_function("concurrent_stt_10x30s", |b| { | ||
b.iter(|| { | ||
runtime.block_on(async { | ||
let (sender, mut receiver) = create_whisper_channel().await.unwrap(); | ||
|
||
for file in &test_files { | ||
let input = AudioInput { | ||
path: file.clone(), | ||
device: "test_device".to_string(), | ||
}; | ||
sender.send(input).unwrap(); | ||
} | ||
|
||
for _ in 0..test_files.len() { | ||
receiver.recv().await.unwrap(); | ||
} | ||
}); | ||
}) | ||
}); | ||
|
||
for file in test_files { | ||
std::fs::remove_file(file).unwrap(); | ||
} | ||
} | ||
|
||
fn benchmark_large_file(c: &mut Criterion) { | ||
let whisper_model = WhisperModel::new().unwrap(); | ||
let large_file = "large_test_audio.wav"; | ||
generate_large_audio_file(large_file, 10); | ||
|
||
c.bench_function("stt_10min_audio", |b| { | ||
b.iter(|| { | ||
stt(black_box(large_file), black_box(&whisper_model)).unwrap(); | ||
}) | ||
}); | ||
|
||
std::fs::remove_file(large_file).unwrap(); | ||
} | ||
|
||
criterion_group! { | ||
name = benches; | ||
config = Criterion::default() | ||
.sample_size(10) | ||
.measurement_time(Duration::from_secs(300)); // Increase to 5 minutes | ||
targets = benchmark_stt, benchmark_concurrent_stt, benchmark_large_file | ||
} | ||
criterion_main!(benches); | ||
|
||
// Benchmarking stt_1min_audio: Warming up for 3.0000 s | ||
// Warning: Unable to complete 10 samples in 60.0s. You may wish to increase target time to 143.6s. | ||
// stt_1min_audio time: [12.127 s 13.636 s 15.211 s] | ||
|
||
// Benchmarking concurrent_stt_10x30s: Warming up for 3.0000 s | ||
// Warning: Unable to complete 10 samples in 60.0s. You may wish to increase target time to 1334.5s. | ||
// concurrent_stt_10x30s time: [133.02 s 138.45 s 144.25 s] | ||
// Found 2 outliers among 10 measurements (20.00%) | ||
// 1 (10.00%) low mild | ||
// 1 (10.00%) high mild | ||
|
||
// Benchmarking stt_10min_audio: Warming up for 3.0000 s | ||
// Warning: Unable to complete 10 samples in 60.0s. You may wish to increase target time to 168.5s. | ||
// stt_10min_audio time: [19.699 s 21.192 s 23.431 s] | ||
// Found 2 outliers among 10 measurements (20.00%) | ||
// 1 (10.00%) low mild | ||
// 1 (10.00%) high severe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// cargo bench --bench pcm_decode_benchmark | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
use screenpipe_audio::pcm_decode::pcm_decode; | ||
use std::path::PathBuf; | ||
|
||
fn benchmark_pcm_decode(c: &mut Criterion) { | ||
// Assuming you have a sample audio file in your project for testing | ||
let test_file_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) | ||
.join("test_data") | ||
.join("selah.mp3"); | ||
|
||
c.bench_function("pcm_decode", |b| { | ||
b.iter(|| { | ||
let _ = pcm_decode(black_box(&test_file_path)); | ||
}) | ||
}); | ||
} | ||
|
||
criterion_group!(benches, benchmark_pcm_decode); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// cargo bench --bench stt_benchmark | ||
|
||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
use screenpipe_audio::stt::{stt, WhisperModel}; | ||
use std::path::PathBuf; | ||
|
||
fn benchmark_stt(c: &mut Criterion) { | ||
let test_file_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) | ||
.join("test_data") | ||
.join("selah.mp3"); | ||
|
||
// Initialize WhisperModel outside the benchmark loop | ||
let whisper_model = WhisperModel::new().expect("Failed to initialize WhisperModel"); | ||
|
||
c.bench_function("stt", |b| { | ||
b.iter(|| { | ||
let _ = stt(black_box(&test_file_path.to_str().unwrap()), &whisper_model); | ||
}) | ||
}); | ||
} | ||
|
||
criterion_group!(benches, benchmark_stt); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.