`preprocessor` in `exportables` but not exported
State: closed | Pull request: no
Labels: name: bug

**Describe the bug**

The `preprocessor` is an instance of `Exportable` and yet it is not exported with `model.export()`

**Steps/Code to reproduce bug**


```py
>> exportables = []
>> for m in model.modules():
        if isinstance(m, Exportable):
          exportables.append(m)
>> exportables
[EncDecCTCModelBPE(
   (preprocessor): AudioToMelSpectrogramPreprocessor(
     (featurizer): FilterbankFeaturesTA(
       (_mel_spec_extractor): MelSpectrogram(
         (spectrogram): Spectrogram()
         (mel_scale): MelScale()
       )
     )
   )
   (encoder): ConformerEncoder(
     (pre_encode): ConvSubsampling(
       (out): Linear(in_features=10240, out_features=512, bias=True)
       (conv): Sequential(
         (0): Conv2d(1, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
         (1): ReLU(inplace=True)
         (2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
         (3): ReLU(inplace=True)
       )
     )
     (pos_enc): RelPositionalEncoding(
       (dropout): Dropout(p=0.1, inplace=False)
     )
     (layers): ModuleList(
       (0-17): 18 x ConformerLayer(
         (norm_feed_forward1): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
         (feed_forward1): ConformerFeedForward(
           (linear1): Linear(in_features=512, out_features=2048, bias=True)
           (activation): Swish()
           (dropout): Dropout(p=0.1, inplace=False)
           (linear2): Linear(in_features=2048, out_features=512, bias=True)
         )
         (norm_conv): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
         (conv): ConformerConvolution(
           (pointwise_conv1): Conv1d(512, 1024, kernel_size=(1,), stride=(1,))
           (depthwise_conv): CausalConv1D(512, 512, kernel_size=(31,), stride=(1,), groups=512)
           (batch_norm): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
           (activation): Swish()
           (pointwise_conv2): Conv1d(512, 512, kernel_size=(1,), stride=(1,))
         )
         (norm_self_att): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
         (self_attn): RelPositionMultiHeadAttention(
           (linear_q): Linear(in_features=512, out_features=512, bias=True)
           (linear_k): Linear(in_features=512, out_features=512, bias=True)
           (linear_v): Linear(in_features=512, out_features=512, bias=True)
           (linear_out): Linear(in_features=512, out_features=512, bias=True)
           (dropout): Dropout(p=0.1, inplace=False)
           (linear_pos): Linear(in_features=512, out_features=512, bias=False)
         )
         (norm_feed_forward2): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
         (feed_forward2): ConformerFeedForward(
           (linear1): Linear(in_features=512, out_features=2048, bias=True)
           (activation): Swish()
           (dropout): Dropout(p=0.1, inplace=False)
           (linear2): Linear(in_features=2048, out_features=512, bias=True)
         )
         (dropout): Dropout(p=0.1, inplace=False)
         (norm_out): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
       )
     )
   )
   (decoder): ConvASRDecoder(
     (decoder_layers): Sequential(
       (0): Conv1d(512, 129, kernel_size=(1,), stride=(1,))
     )
   )
   (loss): CTCLoss()
   (spec_augmentation): SpectrogramAugmentation(
     (spec_augment): SpecAugment()
   )
   (_wer): WERBPE()
 ),
 AudioToMelSpectrogramPreprocessor(
   (featurizer): FilterbankFeaturesTA(
     (_mel_spec_extractor): MelSpectrogram(
       (spectrogram): Spectrogram()
       (mel_scale): MelScale()
     )
   )
 ),
 ConformerEncoder(
   (pre_encode): ConvSubsampling(
     (out): Linear(in_features=10240, out_features=512, bias=True)
     (conv): Sequential(
       (0): Conv2d(1, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
       (1): ReLU(inplace=True)
       (2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
       (3): ReLU(inplace=True)
     )
   )
   (pos_enc): RelPositionalEncoding(
     (dropout): Dropout(p=0.1, inplace=False)
   )
   (layers): ModuleList(
     (0-17): 18 x ConformerLayer(
       (norm_feed_forward1): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
       (feed_forward1): ConformerFeedForward(
         (linear1): Linear(in_features=512, out_features=2048, bias=True)
         (activation): Swish()
         (dropout): Dropout(p=0.1, inplace=False)
         (linear2): Linear(in_features=2048, out_features=512, bias=True)
       )
       (norm_conv): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
       (conv): ConformerConvolution(
         (pointwise_conv1): Conv1d(512, 1024, kernel_size=(1,), stride=(1,))
         (depthwise_conv): CausalConv1D(512, 512, kernel_size=(31,), stride=(1,), groups=512)
         (batch_norm): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
         (activation): Swish()
         (pointwise_conv2): Conv1d(512, 512, kernel_size=(1,), stride=(1,))
       )
       (norm_self_att): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
       (self_attn): RelPositionMultiHeadAttention(
         (linear_q): Linear(in_features=512, out_features=512, bias=True)
         (linear_k): Linear(in_features=512, out_features=512, bias=True)
         (linear_v): Linear(in_features=512, out_features=512, bias=True)
         (linear_out): Linear(in_features=512, out_features=512, bias=True)
         (dropout): Dropout(p=0.1, inplace=False)
         (linear_pos): Linear(in_features=512, out_features=512, bias=False)
       )
       (norm_feed_forward2): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
       (feed_forward2): ConformerFeedForward(
         (linear1): Linear(in_features=512, out_features=2048, bias=True)
         (activation): Swish()
         (dropout): Dropout(p=0.1, inplace=False)
         (linear2): Linear(in_features=2048, out_features=512, bias=True)
       )
       (dropout): Dropout(p=0.1, inplace=False)
       (norm_out): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
     )
   )
 ),
 ConvASRDecoder(
   (decoder_layers): Sequential(
     (0): Conv1d(512, 129, kernel_size=(1,), stride=(1,))
   )
 )]
```


**Expected behavior**

```py
m, descriptions = model.export(MODEL_OUT)
```
should create a model that contains the preprocessor and the rest of the model.
However, the exported model skips the preprocessor

**Environment overview (please complete the following information)**

 - Method of NeMo install: `pip install nemo_toolkit[all]`

**Environment details**

Otherwise, please provide:
- OS version: macOS 14.1
- PyTorch version: 3.10.13
- Python version: 2.1.0

**Additional context**

Trying to convert Conformer model to CoreML


This is by (forced) design. Preprocessor is exportable in one very specific case, when you use the torchaudio backend of the preprocessor. Otherwise it is not exportable. There's no easy way to declare a class is exportable in exactly one case where it's instance is derived from a mirrored API in torchaudio, so we just do the blanket exportable marker for preprocessor. 

We have separate instructions to export the preprocessor - https://github.com/NVIDIA/NeMo/pull/5512