Views
No views yet
save_pretrained export recovered
from smart-turn-v3.1-gpu.onnx.config.json: SmartTurnV3 config with model_type = "smart_turn_v3".model.safetensors: FP32 model weights.preprocessor_config.json: Whisper feature extractor config for 8-second audio.smart_turn Python package that defines and
registers SmartTurnV3Config and SmartTurnV3Model.1pip install torch==2.8.* transformers librosa numpy
2
3# Install your smart_turn package, or run inside the smart-turn project with:
4export PYTHONPATH=/path/to/smart-turn-onnx/src:${PYTHONPATH}demo_smart_turn.py and run:python demo_smart_turn.py /path/to/audio.wav1from __future__ import annotations
2
3import sys
4from pathlib import Path
5
6import librosa
7import numpy as np
8import torch
9from transformers import WhisperFeatureExtractor
10
11from smart_turn.models import load_model
12
13
14REPO_ID = "MigoXV/smart-turn-v3.1"
15SAMPLE_RATE = 16000
16WINDOW_SECONDS = 8
17THRESHOLD = 0.5
18
19
20def load_audio_window(path: str | Path) -> np.ndarray:
21 audio, sr = librosa.load(path, sr=None, mono=True)
22
23 if sr != SAMPLE_RATE:
24 audio = librosa.resample(audio, orig_sr=sr, target_sr=SAMPLE_RATE)
25
26 if audio.dtype != np.float32:
27 audio = audio.astype(np.float32)
28
29 max_abs = np.max(np.abs(audio)) if audio.size else 0.0
30 if max_abs > 1.0:
31 audio = audio / max_abs
32
33 max_samples = WINDOW_SECONDS * SAMPLE_RATE
34 if audio.size >= max_samples:
35 return audio[-max_samples:]
36
37 padding = max_samples - audio.size
38 return np.pad(audio, (padding, 0), mode="constant", constant_values=0)
39
40
41def predict(audio_path: str | Path, device: str = "cpu") -> tuple[int, float]:
42 torch_device = torch.device(device)
43 dtype = torch.float32
44
45 model = load_model(REPO_ID).to(device=torch_device, dtype=dtype).eval()
46 feature_extractor = WhisperFeatureExtractor.from_pretrained(REPO_ID)
47
48 audio = load_audio_window(audio_path)
49 inputs = feature_extractor(
50 audio,
51 sampling_rate=SAMPLE_RATE,
52 return_tensors="np",
53 padding="max_length",
54 max_length=WINDOW_SECONDS * SAMPLE_RATE,
55 truncation=True,
56 do_normalize=True,
57 )
58
59 input_features = torch.from_numpy(
60 inputs.input_features.astype(np.float32)
61 ).to(device=torch_device, dtype=dtype)
62
63 with torch.no_grad():
64 probability = model(input_features=input_features)["logits"].view(-1).item()
65
66 prediction = 1 if probability > THRESHOLD else 0
67 return prediction, probability
68
69
70if __name__ == "__main__":
71 if len(sys.argv) != 2:
72 raise SystemExit("Usage: python demo_smart_turn.py /path/to/audio.wav")
73
74 pred, prob = predict(sys.argv[1], device="cuda" if torch.cuda.is_available() else "cpu")
75 print(f"prediction={pred} probability={prob:.8f}")[0, 1].prediction = 1 means the segment is considered complete when
probability > 0.5.WhisperEncoder + attention pooling + binary head.