Views
No views yet
openai/whisper-small.enpip install torch transformers datasets numpy scikit-learn1import torch
2import torch.nn as nn
3import torch.nn.functional as F
4from transformers import WhisperFeatureExtractor, WhisperModel
5import numpy as np
6
7# Define the model class (same as training)
8class WhisperClassifier(nn.Module):
9 def __init__(self, model_name="openai/whisper-small.en", num_accent_classes=23, num_gender_classes=2,
10 freeze_encoder=True, dropout_rate=0.3):
11 super().__init__()
12
13 self.whisper = WhisperModel.from_pretrained(model_name)
14
15 if freeze_encoder:
16 for param in self.whisper.encoder.parameters():
17 param.requires_grad = False
18
19 self.hidden_size = self.whisper.config.d_model
20 self.dropout = nn.Dropout(dropout_rate)
21
22 # Accent classification head
23 self.accent_classifier = nn.Sequential(
24 nn.Linear(self.hidden_size, 512),
25 nn.ReLU(),
26 nn.Dropout(dropout_rate),
27 nn.Linear(512, 256),
28 nn.ReLU(),
29 nn.Dropout(dropout_rate),
30 nn.Linear(256, num_accent_classes)
31 )
32
33 # Gender classification head
34 self.gender_classifier = nn.Sequential(
35 nn.Linear(self.hidden_size, 256),
36 nn.ReLU(),
37 nn.Dropout(dropout_rate),
38 nn.Linear(256, 128),
39 nn.ReLU(),
40 nn.Dropout(dropout_rate),
41 nn.Linear(128, num_gender_classes)
42 )
43
44 self.num_accent_classes = num_accent_classes
45 self.num_gender_classes = num_gender_classes
46
47 def forward(self, input_features, accent_labels=None, gender_labels=None):
48 encoder_outputs = self.whisper.encoder(input_features)
49 hidden_states = encoder_outputs.last_hidden_state
50 pooled_output = hidden_states.mean(dim=1)
51 pooled_output = self.dropout(pooled_output)
52
53 accent_logits = self.accent_classifier(pooled_output)
54 gender_logits = self.gender_classifier(pooled_output)
55
56 return {
57 'accent_logits': accent_logits,
58 'gender_logits': gender_logits,
59 }
60
61# Load the trained model
62device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
63model = WhisperClassifier()
64
65# Load the trained weights
66model.load_state_dict(torch.load("./model_step1000.safetensors", map_location=device))
67model.to(device)
68model.eval()
69
70# Initialize feature extractor
71feature_extractor = WhisperFeatureExtractor.from_pretrained("openai/whisper-small.en")1def predict_audio(audio_file_path, model, feature_extractor, device):
2 """
3 Predict accent and gender from an audio file
4
5 Args:
6 audio_file_path: Path to audio file (.wav, .mp3, etc.)
7 model: Trained WhisperClassifier model
8 feature_extractor: Whisper feature extractor
9 device: torch device (cuda/cpu)
10
11 Returns:
12 Dictionary with predictions and confidence scores
13 """
14 import librosa
15
16 # Load audio file
17 audio, sr = librosa.load(audio_file_path, sr=16000, mono=True)
18
19 # Extract features
20 inputs = feature_extractor(
21 audio,
22 sampling_rate=sr,
23 return_tensors="pt"
24 )
25
26 # Move to device
27 input_features = inputs.input_features.to(device)
28
29 # Get predictions
30 with torch.no_grad():
31 outputs = model(input_features=input_features)
32
33 # Get probabilities
34 accent_probs = F.softmax(outputs["accent_logits"], dim=-1)
35 gender_probs = F.softmax(outputs["gender_logits"], dim=-1)
36
37 # Get predictions
38 accent_pred = torch.argmax(accent_probs, dim=-1).item()
39 gender_pred = torch.argmax(gender_probs, dim=-1).item()
40
41 # Get confidence scores
42 accent_confidence = accent_probs[0, accent_pred].item()
43 gender_confidence = gender_probs[0, gender_pred].item()
44
45 # Map predictions to labels
46 accent_names = [
47 'african', 'australia', 'bermuda', 'canada', 'england', 'hongkong',
48 'indian', 'ireland', 'malaysia', 'newzealand', 'philippines',
49 'scotland', 'singapore', 'southafrica', 'us', 'wales'
50 # Add all 23 accent names based on your dataset
51 ]
52
53 accent_name = accent_names[accent_pred] if accent_pred < len(accent_names) else f"accent_{accent_pred}"
54 gender_name = "male" if gender_pred == 0 else "female"
55
56 return {
57 'accent': accent_name,
58 'accent_confidence': accent_confidence,
59 'gender': gender_name,
60 'gender_confidence': gender_confidence
61 }
62
63# Example usage
64result = predict_audio("path/to/your/audio.wav", model, feature_extractor, device)
65print(f"Predicted Accent: {result['accent']} (confidence: {result['accent_confidence']:.3f})")
66print(f"Predicted Gender: {result['gender']} (confidence: {result['gender_confidence']:.3f})")1def predict_batch(audio_files, model, feature_extractor, device, batch_size=8):
2 """
3 Predict accent and gender for multiple audio files
4 """
5 import librosa
6 from torch.utils.data import DataLoader, Dataset
7
8 class AudioDataset(Dataset):
9 def __init__(self, audio_files):
10 self.audio_files = audio_files
11
12 def __len__(self):
13 return len(self.audio_files)
14
15 def __getitem__(self, idx):
16 audio, sr = librosa.load(self.audio_files[idx], sr=16000, mono=True)
17 inputs = feature_extractor(audio, sampling_rate=sr, return_tensors="pt")
18 return inputs.input_features.squeeze(0)
19
20 dataset = AudioDataset(audio_files)
21 dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=False)
22
23 results = []
24 model.eval()
25
26 with torch.no_grad():
27 for batch in dataloader:
28 batch = batch.to(device)
29 outputs = model(input_features=batch)
30
31 accent_probs = F.softmax(outputs["accent_logits"], dim=-1)
32 gender_probs = F.softmax(outputs["gender_logits"], dim=-1)
33
34 accent_preds = torch.argmax(accent_probs, dim=-1)
35 gender_preds = torch.argmax(gender_probs, dim=-1)
36
37 for i in range(len(batch)):
38 results.append({
39 'accent_id': accent_preds[i].item(),
40 'accent_confidence': accent_probs[i, accent_preds[i]].item(),
41 'gender_id': gender_preds[i].item(),
42 'gender_confidence': gender_probs[i, gender_preds[i]].item(),
43 })
44
45 return results1def preprocess_custom_audio(audio_array, sample_rate, target_sr=16000):
2 """
3 Preprocess custom audio data
4 """
5 import librosa
6
7 # Resample if needed
8 if sample_rate != target_sr:
9 audio_array = librosa.resample(audio_array, orig_sr=sample_rate, target_sr=target_sr)
10
11 # Ensure mono
12 if len(audio_array.shape) > 1:
13 audio_array = librosa.to_mono(audio_array)
14
15 # Normalize
16 audio_array = audio_array / np.max(np.abs(audio_array))
17
18 return audio_array1def get_top_k_predictions(audio_file, model, feature_extractor, device, k=3):
2 """
3 Get top-k accent predictions with confidence scores
4 """
5 # ... (load and preprocess audio as above)
6
7 with torch.no_grad():
8 outputs = model(input_features=input_features)
9 accent_probs = F.softmax(outputs["accent_logits"], dim=-1)
10
11 # Get top-k predictions
12 top_k_probs, top_k_indices = torch.topk(accent_probs, k, dim=-1)
13
14 results = []
15 for i in range(k):
16 results.append({
17 'accent_id': top_k_indices[0, i].item(),
18 'confidence': top_k_probs[0, i].item()
19 })
20
21 return results