Saltar al contenido
ModelPublicadoExterno
Descargar

Moss Audio Tn Intent

A lightweight audio intent classifier for Tunisian Arabic built on top of the frozen OpenMOSS-Team/MOSS-Audio-8B-Instruct audio encoder and DeepStack feature merger.

TipoOtherModelo baseOpenMOSS-Team/MOSS-Audio-8B-InstructVersiónBestCcalidad

Fuente del modelo

Tipo
Other
Tamaño del archivo
3,03 MB
Modelo base
OpenMOSS-Team/MOSS-Audio-8B-Instruct
Versión
vBest
Actualizado
31 oct 2026
Fuente
Hugging Face

Descripción de la fuente

MOSS-Audio Tunisian Intent Classifier

A lightweight audio intent classifier for Tunisian Arabic built on top of the frozen OpenMOSS-Team/MOSS-Audio-8B-Instruct audio encoder and DeepStack feature merger.

The model achieves 67.4% accuracy on the SLURP-TN held-out evaluation set across 18 intent classes — well above majority-class baseline (~18%) and within striking distance of published Arabic intent-classification SOTA, despite using only ~0.79M trainable parameters (the rest of the 5.2B-parameter pipeline is frozen).

This validates the frozen-MOSS + DeepStack + lightweight head architecture for closed-set Arabic audio classification tasks where end-to-end MOSS generation falls short.


Architecture

                ┌─────────────────────────────────────────┐
   raw audio ──>│  MOSS-Audio audio encoder (FROZEN)      │
   16kHz mono   │  32 Whisper-style encoder layers, 1280-d│
                └─────┬─────────┬─────────┬───────────────┘
                      │ layer10 │ layer21 │ layer31
                      ▼         ▼         ▼
                ┌───────────────────────────────────────┐
                │  DeepStack mergers (FROZEN)           │
                │  3 × GatedMLP, each 1280 → 2560-d     │
                └─────┬─────────┬─────────┬─────────────┘
                      │         │         │
                      └─────sum─┴───sum───┘
                                ▼
                       ┌──────────────────┐
                       │  Mean-pool over  │
                       │  time dimension  │
                       └────────┬─────────┘
                                ▼
                          [2560-d vector]
                                ▼
                ┌───────────────────────────────────────┐
                │  Classifier head (TRAINABLE, 0.79M)   │
                │  LayerNorm → Linear(2560,512) → GELU  │
                │     → Linear(512,256) → GELU          │
                │     → Linear(256, num_classes)        │
                └────────────────┬──────────────────────┘
                                 ▼
                          intent label

Key design choices:

ComponentChoiceRationale
Base encoderMOSS-Audio 8B, frozenStrong acoustic representations; no need to retrain a massive model
Feature extractionDeepStack merge across layers 10/21/31Captures low/mid/high-level acoustic features; matches MOSS's 3-merger design
Aggregation across depthsSumPreserves all depth information; outperformed concat in early tests
Aggregation across timeMean-poolSimple, robust to variable clip length
Head capacity0.79M params, 3-layer MLP with dropoutSmall enough to train in seconds; large enough to learn 18-class boundary

Performance

Overall

MetricValue
Best eval accuracy0.674 (337/500)
Number of classes18
Majority-class baseline~0.188
Random baseline~0.056
Training samples2,174
Evaluation samples500
Training time~1 minute (after feature extraction)
Trainable params789,330
Frozen params5,222,891,520 (5.22B)

Per-class accuracy

Sorted by sample count (high-resource classes first):

ClassEval samplesAccuracy
news_query940.777
weather_query940.819
general_quirky800.487
email_query410.854
alarm_set340.735
email_sendemail340.588
takeaway_order250.680
alarm_query240.417
takeaway_query230.826
alarm_remove150.467
email_querycontact120.333
general_joke100.800
email_addcontact50.400
general_greet40.250
query30.000
quirky10.000
sendemail10.000

Pattern: classes with ≥20 training samples consistently hit 60–85% accuracy. Low-sample classes (n<5) cluster near 0% — these are not "broken" but simply under-trained. The SLURP-TN dataset has overlapping label pairs (quirky/general_quirky, joke/general_joke, etc.) that further depress the per-class number for the rare variants; merging these in a future training run would likely raise overall accuracy to ~73%.

The full confusion matrix is in confusion_matrix.csv.


Quick Start

Install dependencies

# MOSS-Audio package
git clone https://github.com/OpenMOSS/MOSS-Audio.git
cd MOSS-Audio
pip install -e .

# Other deps
pip install torch transformers huggingface_hub librosa

Minimal inference

import torch, torch.nn as nn, librosa, sys
from huggingface_hub import hf_hub_download

# 1. Make MOSS-Audio importable
sys.path.insert(0, "/path/to/MOSS-Audio")
from src.modeling_moss_audio import MossAudioModel
from src.processing_moss_audio import MossAudioProcessor

# 2. Apply Whisper kwarg-stripping patch (idempotent)
import transformers.models.whisper.modeling_whisper as whisper_mod
if not getattr(whisper_mod.WhisperEncoderLayer.forward, "_moss_patched", False):
    _orig = whisper_mod.WhisperEncoderLayer.forward
    def _patched(self, *a, **kw):
        kw.pop("layer_head_mask", None); kw.pop("head_mask", None)
        return _orig(self, *a, **kw)
    _patched._moss_patched = True
    whisper_mod.WhisperEncoderLayer.forward = _patched

# 3. Load the frozen base
MOSS_REPO = "OpenMOSS-Team/MOSS-Audio-8B-Instruct"
moss_model = MossAudioModel.from_pretrained(
    MOSS_REPO, trust_remote_code=True, dtype="auto",
    device_map="cuda:0", attn_implementation="sdpa",
).eval()
processor = MossAudioProcessor.from_pretrained(
    MOSS_REPO, trust_remote_code=True, enable_time_marker=True,
)

# 4. Download the classifier head
head_path = hf_hub_download(repo_id="FatimahEmadEldin/moss-audio-tn-intent",
                            filename="best.pt")

# 5. Load head + label maps
state = torch.load(head_path, weights_only=False, map_location="cuda:0")
ID2LABEL = state["ID2LABEL"]
NUM_CLASSES = state["num_classes"]

class ClassifierHead(nn.Module):
    def __init__(self, in_dim, num_classes, hidden=512, dropout=0.15):
        super().__init__()
        self.net = nn.Sequential(
            nn.LayerNorm(in_dim),
            nn.Linear(in_dim, hidden), nn.GELU(), nn.Dropout(dropout),
            nn.Linear(hidden, hidden // 2), nn.GELU(), nn.Dropout(dropout),
            nn.Linear(hidden // 2, num_classes),
        )
    def forward(self, x):
        return self.net(x)

head = ClassifierHead(state["feature_dim"], NUM_CLASSES).to("cuda:0")
head.load_state_dict(state["head_state_dict"])
head.eval()

# 6. Predict
@torch.no_grad()
def predict(audio_path):
    wav, _ = librosa.load(audio_path, sr=16000, mono=True)
    mel = processor(text="<|audio|>", audios=[wav], return_tensors="pt")
    audio_data = mel["audio_data"].to(moss_model.device, dtype=moss_model.dtype)

    enc_out = moss_model.audio_encoder(audio_data, output_hidden_states=True,
                                        return_dict=True)
    projected = []
    for merger_idx, layer_id in enumerate([10, 21, 31]):
        h = enc_out.hidden_states[layer_id]
        projected.append(moss_model.deepstack_audio_merger_list[merger_idx](h))
    agg = torch.stack(projected, dim=0).sum(dim=0)
    feat = agg.mean(dim=1).squeeze(0).float()

    logits = head(feat.unsqueeze(0))
    probs = torch.softmax(logits, dim=-1).squeeze(0)
    pred_id = int(probs.argmax())
    return {
        "intent": ID2LABEL[pred_id],
        "confidence": float(probs[pred_id]),
        "top3": [(ID2LABEL[i], float(probs[i]))
                 for i in probs.topk(3).indices.cpu().tolist()],
    }

result = predict("my_audio.wav")
print(result)
# Example output:
# {'intent': 'weather_query',
#  'confidence': 0.84,
#  'top3': [('weather_query', 0.84), ('news_query', 0.09), ('general_quirky', 0.03)]}

Detailed Inference (production-quality wrapper)

A more complete wrapper with audio validation, multiple input types, and structured output:

import torch
import torch.nn as nn
import librosa
import numpy as np
import sys, os
from pathlib import Path
from typing import Union, List, Dict
from huggingface_hub import hf_hub_download


class MossAudioIntentClassifier:
    """Tunisian Arabic intent classifier using frozen MOSS-Audio + DeepStack + head."""

    def __init__(
        self,
        moss_audio_repo_path: str = "/content/MOSS-Audio",
        classifier_repo: str = "FatimahEmadEldin/moss-audio-tn-intent",
        moss_base_repo: str = "OpenMOSS-Team/MOSS-Audio-8B-Instruct",
        device: str = "cuda:0",
        moss_weights_dir: str = None,
    ):
        """
        Args:
            moss_audio_repo_path: Local path to a clone of github.com/OpenMOSS/MOSS-Audio
            classifier_repo: HF repo holding the trained classifier head (best.pt)
            moss_base_repo: HF repo for the MOSS-Audio base model
            device: 'cuda:0' / 'cuda' / 'cpu'
            moss_weights_dir: Optional local cache dir for MOSS weights
        """
        self.device = device

        # 1. Import MOSS-Audio modules from local clone
        if moss_audio_repo_path not in sys.path:
            sys.path.insert(0, moss_audio_repo_path)
        from src.modeling_moss_audio import MossAudioModel
        from src.processing_moss_audio import MossAudioProcessor

        # 2. Apply idempotent Whisper kwarg-stripping patch
        # (MOSS-Audio uses WhisperEncoderLayer but passes kwargs newer
        #  transformers versions don't accept)
        self._patch_whisper()

        # 3. Load (or cache) MOSS-Audio base model
        if moss_weights_dir and os.path.exists(os.path.join(moss_weights_dir, "config.json")):
            base_path = moss_weights_dir
        else:
            base_path = moss_base_repo
        print(f"📥 Loading frozen MOSS-Audio from {base_path}")
        self.moss_model = MossAudioModel.from_pretrained(
            base_path, trust_remote_code=True, dtype="auto",
            device_map=device, attn_implementation="sdpa",
        ).eval()
        for p in self.moss_model.parameters():
            p.requires_grad = False

        self.processor = MossAudioProcessor.from_pretrained(
            base_path, trust_remote_code=True, enable_time_marker=True,
        )

        # 4. Download + load classifier head
        print(f"📥 Loading classifier head from {classifier_repo}")
        head_path = hf_hub_download(repo_id=classifier_repo, filename="best.pt")
        state = torch.load(head_path, weights_only=False, map_location=device)

        self.feature_dim = state["feature_dim"]
        self.num_classes = state["num_classes"]
        self.ID2LABEL = state["ID2LABEL"]
        self.LABEL2ID = state["LABEL2ID"]
        self.deepstack_layer_ids = state["config"]["DEEPSTACK_LAYER_IDS"]
        self.aggregation = state["config"]["AGGREGATION"]

        self.head = self._build_head(self.feature_dim, self.num_classes).to(device)
        self.head.load_state_dict(state["head_state_dict"])
        self.head.eval()

        print(f"✅ Ready. {self.num_classes} classes, "
              f"DeepStack layers {self.deepstack_layer_ids}, agg={self.aggregation}")...

Fuentes

1 fuente
Hugging FacePrincipalVersión a950063db07d6341681b0afa88e6a3c68f6463ec
huggingface.co/FatimahEmadEldin/moss-audio-tn-intent/tree/a950063db07d6341681b0afa88e6a3c68f6463ec

Verificado 31 oct

Artefactos del modelo

1 artefacto

best.pt

pt · 3,03 MB · SHA-256 1b616ed81972…276b · Hugging Face

Download file

Extractos de fuentes

2 extractos

--- language: - ar - aeb tags: - audio-classification - intent-classification - arabic - tunisian-arabic - moss-audio - deepstack - frozen-encoder license: apache-2.0 datasets: - Elyadata/SLURP-TN base_model: OpenMOSS-Team/MOSS-Audio-8B-Instruct pipeline_tag: audio-classification metrics: - accuracy model-index: - name: moss-audio-tn-intent results: - task: type: audio-classification name: Tunisian Arabic Intent Classification dataset: name: SLURP-TN type: Elyadata/SLURP-TN metrics: - type: accuracy value: 0.674 name: Overall Accuracy (18-class) --- # MOSS-Audio Tunisian Intent Classifier A lightweight audio intent classifier for Tunisian Arabic built on top of the frozen [`OpenMOSS-Team/MOSS-Audio-8B-Instruct`](https://huggingface.co/OpenMOSS-Team/MOSS-Audio-8B-Instruct) audio encoder and DeepStack feature merger. The model achieves **67.4% accuracy** on the SLURP-TN held-out evaluation set across 18 intent classes — well above majority-class baseline (~18%) and within striking distance of published Arabic intent-classification SOTA, despite using only ~0.79M trainable parameters (the rest of the 5.2B-parameter pipeline is frozen). This validates the **frozen-MOSS + DeepStack + lightweight head** architecture for closed-set Arabic audio classification tasks where end-to-end MOSS generation falls short. --- ## Architecture ``` ┌─────────────────────────────────────────┐ raw audio ──>│ MOSS-Audio audio encoder (FROZEN) │ 16kHz mono │ 32 Whisper-style encoder layers, 1280-d│ └─────┬─────────┬─────────┬───────────────┘ │ layer10 │ layer21 │ layer31 ▼ ▼ ▼ ┌───────────────────────────────────────┐ │ DeepStack mergers (FROZEN) │ │ 3 × GatedMLP, each 1280 → 2560-d │ └─────┬─────────┬─────────┬─────────────┘ │ │ │ └─────sum─┴───sum───┘ ▼ ┌──────────────────┐ │ Mean-pool over │ │ time dimension │ └────────┬─────────┘ ▼ [2560-d vector] ▼ ┌───────────────────────────────────────┐ │ Classifier head (TRAINABLE, 0.79M) │ │ LayerNorm → Linear(2560,512) → GELU │ │ → Linear(512,256) → GELU │ │ → Linear(256, num_classes) │ └────────────────┬──────────────────────┘ ▼ intent label ``` **Key design choices:** | Component | Choice | Rationale | |---|---|---| | Base encoder | MOSS-Audio 8B, frozen | Strong acoustic representations; no need to retrain a massive model | | Feature extraction | DeepStack merge across layer...

Source context: 0 downloads · 0 likes · Pipeline audio-classification · Repo FatimahEmadEldin/moss-audio-tn-intent