Feature Extraction
Transformers
Safetensors
salmonn_2
audio
audio-language-model
audio-understanding
speech
music
custom_code
Instructions to use marcoyang/SALMONN-2-8B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use marcoyang/SALMONN-2-8B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="marcoyang/SALMONN-2-8B", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("marcoyang/SALMONN-2-8B", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 3,096 Bytes
a8ef2f8 f470c42 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | from pathlib import Path
import pytest
import torch
from transformers import AutoTokenizer
from processing_salmonn import SalmonnProcessor
ROOT = Path(__file__).resolve().parents[1]
@pytest.fixture(scope="module")
def processor():
tokenizer = AutoTokenizer.from_pretrained(ROOT, fix_mistral_regex=False)
return SalmonnProcessor(tokenizer)
def test_basic_audio_request(processor):
inputs = processor(
audios=torch.zeros(1600),
sampling_rate=16000,
instruction="Describe the audio.",
)
assert inputs["input_ids"].shape[0] == 1
assert inputs["audio_features"].shape == (1, 10, 128)
assert inputs["audio_lengths"].tolist() == [10]
assert inputs["audio_counts"].tolist() == [1]
def test_text_only_context_does_not_add_audio(processor):
prompt = processor.build_prompt(
"Transcribe the speech.",
context=["howes", "wszelaki"],
)
assert prompt.count("<audio>") == 1
assert "[howes, wszelaki]" in prompt
def test_audio_text_context_preserves_placeholder_order(processor):
waveform = torch.zeros(1600)
context = [
{"text": "howes", "audio": (waveform, 16000)},
{"text": "wszelaki", "audio": (waveform, 16000)},
]
prompt = processor.build_prompt("Transcribe the speech.", context=context)
inputs = processor(
audios=(waveform, 16000),
instruction="Transcribe the speech.",
context=context,
)
assert prompt.count("<audio>") == 3
assert "<audio>howes\n<audio>wszelaki" in prompt
assert inputs["audio_features"].shape == (3, 10, 128)
assert inputs["audio_lengths"].tolist() == [10, 10, 10]
assert inputs["audio_counts"].tolist() == [3]
def test_mixed_context_modalities_are_rejected(processor):
with pytest.raises(ValueError, match="all include audio or all be text-only"):
processor.build_prompt(
"Transcribe the speech.",
context=[
"howes",
{"text": "wszelaki", "audio": (torch.zeros(1600), 16000)},
],
)
def test_formatted_prompt_preserves_custom_audio_placement(processor):
waveform = torch.zeros(1600)
inputs = processor(
audios=[(waveform, 16000), (waveform, 16000)],
formatted_prompt="<audio>Compare this recording with <audio>this example.",
)
assert (inputs["input_ids"] == 151652).sum().item() == 2
assert inputs["audio_counts"].tolist() == [2]
def test_formatted_prompt_validates_placeholder_count(processor):
with pytest.raises(ValueError, match="1 audio placeholders but received 2"):
processor(
audios=[(torch.zeros(1600), 16000), (torch.zeros(1600), 16000)],
formatted_prompt="<audio>Describe both recordings.",
)
def test_instruction_and_formatted_prompt_are_mutually_exclusive(processor):
with pytest.raises(ValueError, match="exactly one"):
processor(
audios=(torch.zeros(1600), 16000),
instruction="Describe the audio.",
formatted_prompt="<audio>Describe the audio.",
)
|