Skip to content

Feature/raven export wrapper - #125

Open
shaing10 wants to merge 16 commits into
masterfrom
feature/raven-export-wrapper
Open

Feature/raven export wrapper#125
shaing10 wants to merge 16 commits into
masterfrom
feature/raven-export-wrapper

Conversation

@shaing10

@shaing10 shaing10 commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds scripts/raven_export.py — exports soundbay checkpoints (ResNet182D, Squeezenet2D) to Raven Intelligence .ravenmodel packages with preprocessing baked in
  • Supports TorchScript (recommended) and ONNX export formats
  • Re-implements PeakNormalize, UnitNormalize, and LibrosaPcen as nn.Modules for TorchScript compatibility
  • Adds --compensate-for-sigmoid flag (recommended): Raven applies sigmoid to model outputs internally, so this option outputs inverse_sigmoid(softmax(logits)) — Raven's sigmoid then recovers exact softmax probabilities that sum to 1.0

Usage

Recommended (until Raven publishes a new version with more DOFs in their post-processing logic): compensate for Raven's sigmoid post-processing

python scripts/raven_export.py /path/to/checkpoint/best.pth \
    --output-dir ~/Raven\ Workbench/Raven\ Intelligence/Models/ \
    --name My_Detector \
    --compensate-for-sigmoid

Raw logits (no activation, Raven applies sigmoid):

python scripts/raven_export.py /path/to/checkpoint/best.pth \
    --name My_Detector --no-softmax

Why some modules are re-implemented

TorchScript export requires all operations to be nn.Module instances or pure torch ops. Several soundbay preprocessors can't be traced as-is:

Module Why re-implemented Approach
PeakNormalize Plain class with __call__, not nn.Module — TorchScript can't trace it Thin nn.Module wrapper with identical logic (verified: 0.0 diff)
UnitNormalize Same — not nn.Module Same approach (verified: 0.0 diff)
LibrosaPcen Calls librosa.core.pcen (NumPy/SciPy) — can't run in TorchScript Full reimplementation in pure PyTorch with torch.jit.script for the IIR loop. Matches librosa's filter coefficients and lfilter_zi initialization exactly
MinFreqFiltering Uses numpy.floor Replaced with nn.Identity (validated: only min_freq=0 configs are supported; errors on non-zero)

Test plan

  • Exported barks detector with all 3 modes (softmax, no-softmax, compensate-for-sigmoid)
  • Verified compensated model scores sum to exactly 1.0 after Raven's sigmoid
  • Confirmed detection agreement across all export modes on real WAV file
  • Tested in Raven Intelligence with TH=0.2

shaing10 and others added 11 commits April 14, 2026 22:14
Introduces core components for exporting soundbay models to Raven Intelligence:
- RavenExportModel: Wraps trained models with preprocessing pipeline
- PreprocessingPipeline: Embeds resampling and preprocessing from args.yaml
- PeakNormalizeModule/UnitNormalizeModule: Export-compatible normalization
- _get_model_class: Lazy model loading to avoid transformers dependency

The wrapper accepts raw audio input and outputs class probabilities,
matching Raven Intelligence expected interface.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Adds functions to export wrapped models to Raven Intelligence format:
- export_to_onnx: Export to ONNX format (limited by STFT support)
- export_to_torchscript: Export to TorchScript (recommended)
- create_raven_model_package: One-command export from soundbay checkpoint

Creates complete .ravenmodel package including:
- JSON configuration file (.ravenmodel)
- Exported model (model.pt or model.onnx)
- Labels file (labels.txt)

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

Co-Authored-By: Claude <noreply@anthropic.com>
Adds support for packaging pre-existing TorchScript models:
- create_raven_model_package_from_torchscript: Package external .pt models
  with custom labels, sample rate, and duration settings

Adds CLI interface for command-line usage:
  python -m soundbay.raven_export checkpoint.pth --output-dir /path --name MyModel

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

Co-Authored-By: Claude <noreply@anthropic.com>
- Relocate from soundbay/ to scripts/ for better organization
- Add comprehensive usage examples in module docstring:
  - CLI usage for exporting soundbay checkpoints
  - Python API for checkpoint export
  - Python API for packaging existing TorchScript models
- Document output structure and supported architectures
- Add notes on TorchScript vs ONNX and DJL compatibility

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

Co-Authored-By: Claude <noreply@anthropic.com>
Code review fixes:
- Remove duplicated ResNet182D/Squeezenet2D class definitions
- Import model classes directly from soundbay.models (requires transformers)
- Add checkpoint file existence check in from_checkpoint()
- Remove redundant conditional for input_dims
- Move shutil import to top of file
- Add --format CLI option for export format selection

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

Co-Authored-By: Claude <noreply@anthropic.com>
- Add all CLI options to usage example (--format, --no-softmax)
- Add REQUIREMENTS section noting transformers dependency
- Clarify input tensor shapes for both export methods

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

Co-Authored-By: Claude <noreply@anthropic.com>
- PeakNormalizeModule: use global min/max (not per-dimension)
- UnitNormalizeModule: use global mean/std (not per-dimension)
- Add documentation explaining why nn.Module re-implementations are needed
- Reference original implementations in soundbay/data.py

This ensures exported models produce identical results to training.

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

Co-Authored-By: Claude <noreply@anthropic.com>
- Add explicit error for MinFreqFiltering and SlidingWindowNormalize
  (these use numpy/random operations incompatible with TorchScript)
- Document supported vs unsupported preprocessors in module docstring
- Add inline comments referencing original implementations

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

Co-Authored-By: Claude <noreply@anthropic.com>
PeakNormalizeModule and UnitNormalizeModule now use per-sample
normalization with keepdim=True, ensuring correct broadcasting
for any batch size during Raven Intelligence inference.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Shows step-by-step progress during model export:
- Step 1/4: Loading checkpoint and model creation
- Step 2/4: TorchScript tracing
- Step 3/4: Labels file creation
- Step 4/4: Raven config generation

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

Co-Authored-By: Claude <noreply@anthropic.com>
Raven Intelligence applies sigmoid independently to each model output.
Models exported with softmax baked in get double-transformed, compressing
scores into a narrow unusable range. This adds a compensate-for-sigmoid
option that outputs inverse-sigmoid(softmax(logits)), so Ravens sigmoid
recovers exact softmax probabilities (scores sum to 1.0).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@shaing10 shaing10 self-assigned this Apr 14, 2026
@shaing10 shaing10 added the ci-test label to trigger CI flow label Apr 14, 2026
shaing10 and others added 3 commits April 14, 2026 22:38
PeakNormalizeModule and UnitNormalizeModule previously used per-sample
normalization (reducing all dims except batch). The originals in
soundbay/data.py use global min/max/mean/std across all dims. Simplified
to match exactly. Also added validation for MinFreqFiltering to error
if min_freq != 0 (only no-op case is supported for TorchScript export).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The original soundbay PeakNormalize/UnitNormalize use global min/max/mean/std
because they run per-sample inside __getitem__ (no batch dim). When Raven sends
batch_size>1, we must reduce all dims EXCEPT batch to match the original's
per-sample semantics. Added comments explaining the reasoning to prevent
future regressions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@shaing10 shaing10 added ci-test label to trigger CI flow and removed ci-test label to trigger CI flow labels Apr 16, 2026

@mosheman5 mosheman5 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

looks good
do we still new --compensate-for-sigmoid in the default/recommended command?

@shaing10

shaing10 commented May 5, 2026

Copy link
Copy Markdown
Collaborator Author

looks good do we still new --compensate-for-sigmoid in the default/recommended command?

image seems like the new release solved it, I'll change the default

shaing10 and others added 2 commits May 5, 2026 22:14
Current Raven Intelligence releases allow disabling sigmoid post-processing,
so plain softmax output is now the correct default. Demotes --compensate-for-sigmoid
to legacy status (workaround for older Raven versions without this option).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@shaing10
shaing10 requested a review from mosheman5 May 5, 2026 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-test label to trigger CI flow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants