Skip to content

Fix silent all-zero fbank in chunk embedding prep when the 30s model is absent - #17

Merged
praveenperera merged 1 commit into
avencera:masterfrom
attevon-llc:fix/chunk-embedding-fbank-fallback
Sep 16, 2026
Merged

praveenperera merged 1 commit into
avencera:masterfrom
attevon-llc:fix/chunk-embedding-fbank-fallback

Conversation

@attevon-admin

@attevon-admin attevon-admin commented Aug 25, 2026

Copy link
Copy Markdown

Closes #16

The bug

ChunkPrep::compute_chunk_fbank (src/pipeline/chunk_embedding/prep.rs) nested the "does this chunk fit the 30s model?" test inside the "is the 30s model loaded?" test:

let mut fbank = vec![0.0f32; self.largest_fbank_frames * 80];

if chunk_audio.len() <= 480_000 {
    if let Some(fbank_model) = &self.fbank_30s { /* 30s path */ }
    // fbank_30s == None falls through with `fbank` still all zeros
} else if let Some(fbank_model) = &self.fbank_10s { /* 10s path */ }

Ok(fbank)

Because the 10s branch is the else if of the length check, it is unreachable for chunks <= 480_000 samples. With fbank_30s == None a short chunk therefore returns the zeroed buffer allocated up front — a well-formed, all-zero tensor. No error, no panic; just silently wrong embeddings downstream.

run_sequential_chunks in orchestrate.rs:240-269 already does this correctly, keying the fallback off whether the 30s fbank was actually produced rather than off chunk length.

The fix

Extracted the choice into a small pure function so the two conditions are combined and the decision is explicit and testable:

pub(super) fn select_fbank_path(chunk_len: usize, has_30s: bool, has_10s: bool) -> FbankPath {
    if chunk_len <= 480_000 && has_30s {
        FbankPath::ThirtySecond
    } else if has_10s {
        FbankPath::TenSecond
    } else {
        FbankPath::None
    }
}

compute_chunk_fbank now dispatches on FbankPath, so a short chunk with no 30s model falls back to the 10s path exactly as orchestrate.rs does. The 30s and 10s computation bodies are unchanged — this is purely a control-flow correction.

Tests

Four unit tests in prep.rs cover the matrix (30s available, 30s missing, long chunk, no models). The regression test is short_chunk_falls_back_to_10s_when_30s_missing.

Verified on real Apple Silicon hardware (arm64 Mac Studio), since chunk_embedding is gated behind #[cfg(feature = "coreml")] and does not compile on Linux (the objc2* dependencies are Apple-only):

cargo test --release --no-default-features --features openblas-system,online,coreml
  • Before the fix (original nested logic restored, same machine), the regression test fails precisely as expected while the other three pass:

    test ...prep::tests::short_chunk_falls_back_to_10s_when_30s_missing ... FAILED
    assertion `left == right` failed
      left: None
     right: TenSecond
    

    None is exactly the state that yielded the all-zero fbank.

  • After the fix, all four pass and the lib suite is 88 passed; 2 failed out of 90.

The 2 failures (fast_apple_embeddings_match_python_fixture, fast_apple_split_primary_batch_matches_single_tail_path) are pre-existing and unrelated — I confirmed they fail identically with stock, unmodified prep.rs on the same machine (fixture drift in my local model artifacts, not a regression from this change).

Summary by CodeRabbit

  • Bug Fixes
    • Improved audio feature model selection for short audio segments.
    • Short segments now use the 10-second model when the 30-second model is unavailable, instead of producing empty results.
  • Tests
    • Added coverage for model selection across different segment lengths and model availability conditions.

…sent

compute_chunk_fbank treated 'chunk fits in the 30s model' and 'the 30s
model exists' as one condition: for chunk_audio.len() <= 480_000 with
fbank_30s == None it fell through to the end of the function and returned
the all-zero tensor it had allocated, producing silently wrong embeddings
rather than an error.

orchestrate.rs already handles this correctly by falling back to the 10s
model. Route both call sites through a pure select_fbank_path helper so
the choice is explicit and unit-testable.
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f2a56de-f479-47cf-89e6-37dc6d4c69df

📥 Commits

Reviewing files that changed from the base of the PR and between b0756b1 and fe7164b.

📒 Files selected for processing (1)
  • src/pipeline/chunk_embedding/prep.rs

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The chunk embedding preparation path now selects an available fbank model. Short chunks fall back to the 10-second model when the 30-second model is unavailable. Unit tests cover selection and no-model cases.

Changes

Fbank model selection

Layer / File(s) Summary
Fbank selection and preparation
src/pipeline/chunk_embedding/prep.rs
FbankPath and select_fbank_path select the 30-second model, the 10-second model, or no model. compute_chunk_fbank uses this selection before prediction. Unit tests cover short and long chunks, fallback behavior, and unavailable models.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to fe716

This localized change makes short chunks fall back to the available 10-second model instead of producing an all-zero feature buffer; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: preventing silent all-zero fbank output when the 30-second model is absent.
Linked Issues check ✅ Passed The changes address issue #16 by selecting the 10-second model when a short chunk lacks the 30-second model. The added selection logic and regression tests support the required fallback behavior.
Out of Scope Changes check ✅ Passed The changes are limited to fbank model selection and related tests in chunk embedding preparation. No unrelated changes are identified.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 25, 2026

Copy link
Copy Markdown

Greptile Summary

The PR corrects Core ML chunk feature-bank routing so short chunks fall back to the 10-second model when the 30-second model is unavailable.

  • Introduces an explicit, testable feature-bank path selector.
  • Preserves the 30-second path for eligible chunks and the 10-second path for longer chunks.
  • Adds unit coverage for model-availability and chunk-length combinations.

Confidence Score: 5/5

The PR appears safe to merge, with no actionable regressions identified in the corrected feature-bank routing.

The selector sends eligible chunks to the 30-second model and otherwise uses the available 10-second model, matching the established sequential implementation without introducing new buffer, shape, or availability failures.

Important Files Changed

Filename Overview
src/pipeline/chunk_embedding/prep.rs The new selector fixes the silent all-zero fallback while preserving existing model limits, buffer bounds, and sequential-path semantics.

Reviews (1): Last reviewed commit: "fix(chunk-embedding): fall back to 10s f..." | Re-trigger Greptile

@praveenperera
praveenperera merged commit 489aa6b into avencera:master Sep 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chunk embedding prep silently returns an all-zero fbank when the 30s model is absent

3 participants