import os
import torch
import torchaudio
import logging
import numpy as np
import pandas as pd
from transformers import Wav2Vec2Processor, Wav2Vec2Model, Wav2Vec2PreTrainedModel, pipeline

# Set up logging
logging.basicConfig(level=logging.INFO)

# Constants
RECORDINGS_DIR = r"X:\Bidvest_ASC_recordings"  # Directory where the recordings are stored
SAMPLE_RATE = 16000  # Desired sample rate for processing

# Load the CSV file
csv_file_path = r"C:\Users\FourieH\Desktop\final_transcription_results_diarized.csv"  # Update with your actual CSV file path
data = pd.read_csv(csv_file_path)

# Function to modify the hyperlink with a check for NaN values
def modify_hyperlink(original_hyperlink):
    if isinstance(original_hyperlink, str):
        return original_hyperlink.replace(r"\\172.21.18.180\CallCentreAudioFiles", "X:\\")
    return original_hyperlink  # Return as-is if NaN or not a string

# Apply the modified function to the column
data['Modified Hyperlink'] = data['Segment Audio Hyperlink'].apply(modify_hyperlink)

# Updated function to load and preprocess audio as a NumPy array
def load_and_resample_audio(file_path, sample_rate=SAMPLE_RATE):
    waveform, original_sample_rate = torchaudio.load(file_path)

    # Convert to mono if stereo
    if waveform.size(0) > 1:
        waveform = torch.mean(waveform, dim=0, keepdim=True)

    # Resample if the original sample rate differs from the desired sample rate
    if original_sample_rate != sample_rate:
        resampler = torchaudio.transforms.Resample(orig_freq=original_sample_rate, new_freq=sample_rate)
        waveform = resampler(waveform)

    return waveform.squeeze(0).numpy()

class RegressionHead(torch.nn.Module):
    """Classification head for emotions."""

    def __init__(self, config):
        super().__init__()
        self.dense = torch.nn.Linear(config.hidden_size, config.hidden_size)
        self.dropout = torch.nn.Dropout(config.final_dropout)
        self.out_proj = torch.nn.Linear(config.hidden_size, config.num_labels)

    def forward(self, features):
        x = self.dropout(features)
        x = self.dense(x)
        x = torch.tanh(x)
        x = self.dropout(x)
        return self.out_proj(x)

class EmotionModel(Wav2Vec2PreTrainedModel):
    """Speech emotion classifier."""

    def __init__(self, config):
        super().__init__(config)
        self.config = config
        self.wav2vec2 = Wav2Vec2Model(config)
        self.classifier = RegressionHead(config)
        self.init_weights()

    def forward(self, input_values):
        outputs = self.wav2vec2(input_values)
        hidden_states = outputs[0]
        hidden_states = torch.mean(hidden_states, dim=1)
        logits = self.classifier(hidden_states)
        return logits

# Load the emotion classification model from Hugging Face hub
device = 'cpu'
model_name = 'audeering/wav2vec2-large-robust-12-ft-emotion-msp-dim'
processor = Wav2Vec2Processor.from_pretrained(model_name)
model = EmotionModel.from_pretrained(model_name).to(device)
model.eval()  # Set the model to evaluation mode

# Load the audio classification model
logging.info("Loading audio classification model...")
audio_classifier = pipeline("audio-classification", model="somosnlp-hackathon-2022/wav2vec2-base-finetuned-sentiment-classification-MESD")
logging.info("Audio classification model loaded successfully.")

# Define emotion labels for the emotion model
emotion_labels = ['Arousal', 'Dominance', 'Valence']

# Initialize columns for emotion scores
for label in emotion_labels:
    data[f'Emotion Score - {label}'] = None

# Initialize columns for audio classification scores
data['Happiness'] = None
data['Anger'] = None
data['Neutral'] = None

# Function to predict emotions from raw audio signal
def process_func(x: np.ndarray, sampling_rate: int) -> np.ndarray:
    inputs = processor(x, sampling_rate=sampling_rate, return_tensors="pt")
    input_values = inputs['input_values'].to(device)

    with torch.no_grad():
        logits = model(input_values)

    return logits.detach().cpu().numpy()

# Process all audio files in the modified hyperlinks column
for index, row in data.iterrows():
    modified_hyperlink = row['Modified Hyperlink']
    try:
        # Extract filename for logging if modified_hyperlink is valid
        filename = os.path.basename(modified_hyperlink)  
        
        if filename.endswith(".wav"):
            preprocessed_audio = load_and_resample_audio(modified_hyperlink)
            
            # Process emotion prediction
            results = process_func(preprocessed_audio, SAMPLE_RATE)
            for label, score in zip(emotion_labels, results[0]):
                data.at[index, f'Emotion Score - {label}'] = score
                logging.info(f"{filename}: {label}: {score:.4f}")

            # Run audio classification
            classification_results = audio_classifier(preprocessed_audio, sample_rate=SAMPLE_RATE)
            for result in classification_results:
                label = result['label']
                score = result['score']
                if label in data.columns:
                    data.at[index, label] = score
                    logging.info(f"{filename} (Audio Classifier): {label}: {score:.4f}")

    except TypeError:
        logging.warning(f"Skipping entry at index {index} due to TypeError.")
    except Exception as e:
        logging.error(f"Error processing {filename}: {e}")


# Save the updated DataFrame back to a new CSV file
output_csv_path = r"C:\Users\FourieH\Desktop\final_transcription_results_diarizedv2.csv"   # Update with desired output path
data.to_csv(output_csv_path, index=False)

Above is my code below is documetation :

Inference
Optimum Intel can be used to load optimized models from the Hub and create pipelines to run inference with OpenVINO Runtime on a variety of Intel processors (see the full list of supported devices)

Loading
Transformers models
Once your model was exported, you can load it by replacing the AutoModelForXxx class with the corresponding OVModelForXxx.

Copied
- from transformers import AutoModelForCausalLM
+ from optimum.intel import OVModelForCausalLM
  from transformers import AutoTokenizer, pipeline

  model_id = "helenai/gpt2-ov"
- model = AutoModelForCausalLM.from_pretrained(model_id)
  # here the model was already exported so no need to set export=True
+ model = OVModelForCausalLM.from_pretrained(model_id)
  tokenizer = AutoTokenizer.from_pretrained(model_id)
  pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
  results = pipe("He's a dreadful magician and")
As shown in the table below, each task is associated with a class enabling to automatically load your model.

Auto Class	Task
OVModelForSequenceClassification	text-classification
OVModelForTokenClassification	token-classification
OVModelForQuestionAnswering	question-answering
OVModelForAudioClassification	audio-classification
OVModelForImageClassification	image-classification
OVModelForFeatureExtraction	feature-extraction
OVModelForMaskedLM	fill-mask
OVModelForImageClassification	image-classification
OVModelForAudioClassification	audio-classification
OVModelForCausalLM	text-generation-with-past
OVModelForSeq2SeqLM	text2text-generation-with-past
OVModelForSpeechSeq2Seq	automatic-speech-recognition
OVModelForVision2Seq	image-to-text
Diffusers models
Make sure you have 🤗 Diffusers installed. To install diffusers:

Copied
pip install optimum[diffusers]
Copied
- from diffusers import StableDiffusionPipeline
+ from optimum.intel import OVStableDiffusionPipeline

  model_id = "echarlaix/stable-diffusion-v1-5-openvino"
- pipeline = StableDiffusionPipeline.from_pretrained(model_id)
+ pipeline = OVStableDiffusionPipeline.from_pretrained(model_id)
  prompt = "sailing ship in storm by Rembrandt"
  images = pipeline(prompt).images
As shown in the table below, each task is associated with a class enabling to automatically load your model.

Auto Class	Task
OVStableDiffusionPipeline	text-to-image
OVStableDiffusionImg2ImgPipeline	image-to-image
OVStableDiffusionInpaintPipeline	inpaint
OVStableDiffusionXLPipeline	text-to-image
OVStableDiffusionXLImg2ImgPipeline	image-to-image
OVLatentConsistencyModelPipeline	text-to-image
See the reference documentation for more information about parameters, and examples for different tasks.

Compilation
By default the model will be compiled when instantiating an OVModel. In the case where the model is reshaped or placed to another device, the model will need to be recompiled again, which will happen by default before the first inference (thus inflating the latency of the first inference). To avoid an unnecessary compilation, you can disable the first compilation by setting compile=False.

Copied
from optimum.intel import OVModelForQuestionAnswering

model_id = "distilbert/distilbert-base-cased-distilled-squad"
# Load the model and disable the model compilation
model = OVModelForQuestionAnswering.from_pretrained(model_id, compile=False)
To run inference on Intel integrated or discrete GPU, use .to("gpu"). On GPU, models run in FP16 precision by default. (See OpenVINO documentation about installing drivers for GPU inference).

Copied
model.to("gpu")
The model can be compiled:

Copied
model.compile()
Static shape
By default, dynamic shapes are supported, enabling inference for inputs of every shape. To speed up inference, static shapes can be enabled by giving the desired input shapes with .reshape().

Copied
# Fix the batch size to 1 and the sequence length to 40
batch_size, seq_len = 1, 40
model.reshape(batch_size, seq_len)
When fixing the shapes with the reshape() method, inference cannot be performed with an input of a different shape.

Copied

from transformers import AutoTokenizer
from optimum.intel import OVModelForQuestionAnswering

model_id = "distilbert/distilbert-base-cased-distilled-squad"
model = OVModelForQuestionAnswering.from_pretrained(model_id, compile=False)
tokenizer = AutoTokenizer.from_pretrained(model_id)
batch_size, seq_len = 1, 40
model.reshape(batch_size, seq_len)
# Compile the model before the first inference
model.compile()

question = "Which name is also used to describe the Amazon rainforest ?"
context = "The Amazon rainforest, also known as Amazonia or the Amazon Jungle"
tokens = tokenizer(question, context, max_length=seq_len, padding="max_length", return_tensors="np")

outputs = model(**tokens)
For models that handle images, you can also specify the height and width when reshaping your model:

Copied
batch_size, num_images, height, width = 1, 1, 512, 512
pipeline.reshape(batch_size=batch_size, height=height, width=width, num_images_per_prompt=num_images)
images = pipeline(prompt, height=height, width=width, num_images_per_prompt=num_images).images
Configuration
The ov_config parameter allow to provide custom OpenVINO configuration values. This can be used for example to enable full precision inference on devices where FP16 or BF16 inference precision is used by default.

Copied
ov_config = {"INFERENCE_PRECISION_HINT": "f32"}
model = OVModelForSequenceClassification.from_pretrained(model_id, ov_config=ov_config)
Optimum Intel leverages OpenVINO’s model caching to speed up model compiling on GPU. By default a model_cache directory is created in the model’s directory in the Hugging Face Hub cache. To override this, use the ov_config parameter and set CACHE_DIR to a different value. To disable model caching on GPU, set CACHE_DIR to an empty string.

Copied
ov_config = {"CACHE_DIR": ""}
model = OVModelForSequenceClassification.from_pretrained(model_id, device="gpu", ov_config=ov_config)
Weight quantization
You can also apply fp16, 8-bit or 4-bit weight compression on the Linear, Convolutional and Embedding layers when loading your model to reduce the memory footprint and inference latency.

For more information on the quantization parameters checkout the documentation.

If not specified, load_in_8bit will be set to True by default when models larger than 1 billion parameters are exported to the OpenVINO format (with export=True). You can disable it with load_in_8bit=False.

It’s also possible to apply quantization on both weights and activations using the OVQuantizer.

Optimization
🤗 Optimum Intel provides an openvino package that enables you to apply a variety of model compression methods such as quantization, pruning, on many models hosted on the 🤗 hub using the NNCF framework.

Post-training
Quantization is a technique to reduce the computational and memory costs of running inference by representing the weights and / or the activations with lower precision data types like 8-bit or 4-bit.

Weight-only quantization
Quantization can be applied on the model’s Linear, Convolutional and Embedding layers, enabling the loading of large models on memory-limited devices. For example, when applying 8-bit quantization, the resulting model will be x4 smaller than its fp32 counterpart. For 4-bit quantization, the reduction in memory could theoretically reach x8, but is closer to x6 in practice.

8-bit
For the 8-bit weight quantization you can set load_in_8bit=True to load your model’s weights in 8-bit:

Copied
from optimum.intel import OVModelForCausalLM

model_id = "helenai/gpt2-ov"
model = OVModelForCausalLM.from_pretrained(model_id, load_in_8bit=True)

# Saves the int8 model that will be x4 smaller than its fp32 counterpart
model.save_pretrained(saving_directory)
If not specified, load_in_8bit will be set to True by default when models larger than 1 billion parameters are exported to the OpenVINO format (with export=True). You can disable it with load_in_8bit=False.

You can also provide a quantization_config instead to specify additional optimization parameters.

4-bit
For the 4-bit weight quantization, you need a quantization_config to define the optimization parameters, for example:

Copied
from optimum.intel import OVModelForCausalLM, OVWeightQuantizationConfig

quantization_config = OVWeightQuantizationConfig(bits=4)
model = OVModelForCausalLM.from_pretrained(model_id, quantization_config=quantization_config)
You can tune quantization parameters to achieve a better performance accuracy trade-off as follows:

Copied
quantization_config = OVWeightQuantizationConfig(bits=4, sym=False, ratio=0.8, dataset="wikitext2")
By default the quantization scheme will be asymmetric, to make it symmetric you can add sym=True.

For 4-bit quantization you can also specify the following arguments in the quantization configuration :

The group_size parameter will define the group size to use for quantization, -1 it will results in per-column quantization.
The ratio parameter controls the ratio between 4-bit and 8-bit quantization. If set to 0.9, it means that 90% of the layers will be quantized to int4 while 10% will be quantized to int8.
Smaller group_size and ratio values usually improve accuracy at the sacrifice of the model size and inference latency.

Quality of 4-bit weight compressed model can further be improved by employing one of the following data-dependent methods:

AWQ which stands for Activation Aware Quantization is an algorithm that tunes model weights for more accurate 4-bit compression. It slightly improves generation quality of compressed LLMs, but requires significant additional time and memory for tuning weights on a calibration dataset. Please note that it is possible that there will be no matching patterns in the model to apply AWQ, in such case it will be skipped.
Scale Estimation is a method that tunes quantization scales to minimize the L2 error between the original and compressed layers. Providing a dataset is required to run scale estimation. Using this method also incurs additional time and memory overhead.
AWQ and Scale Estimation algorithms can be applied together or separately. For that, provide corresponding arguments to the 4-bit OVWeightQuantizationConfig together with a dataset. For example:

Copied
quantization_config = OVWeightQuantizationConfig(bits=4, sym=False, ratio=0.8, quant_method="awq", scale_estimation=True, dataset="wikitext2")
Static quantization
When applying post-training static quantization, both the weights and the activations are quantized. To apply quantization on the activations, an additional calibration step is needed which consists in feeding a calibration_dataset to the network in order to estimate the quantization activations parameters.

Here is how to apply static quantization on a fine-tuned DistilBERT given your own calibration_dataset:

Copied
from transformers import AutoTokenizer
from optimum.intel import OVQuantizer, OVModelForSequenceClassification, OVConfig, OVQuantizationConfig

model_id = "distilbert-base-uncased-finetuned-sst-2-english"
model = OVModelForSequenceClassification.from_pretrained(model_id, export=True)
tokenizer = AutoTokenizer.from_pretrained(model_id)
# The directory where the quantized model will be saved
save_dir = "ptq_model"

quantizer = OVQuantizer.from_pretrained(model)

# Apply static quantization and export the resulting quantized model to OpenVINO IR format
ov_config = OVConfig(quantization_config=OVQuantizationConfig())
quantizer.quantize(ov_config=ov_config, calibration_dataset=calibration_dataset, save_directory=save_dir)
# Save the tokenizer
tokenizer.save_pretrained(save_dir)
The calibration dataset can also be created easily using your OVQuantizer:

Copied
from functools import partial

def preprocess_function(examples, tokenizer):
    return tokenizer(examples["sentence"], padding="max_length", max_length=128, truncation=True)

# Create the calibration dataset used to perform static quantization
calibration_dataset = quantizer.get_calibration_dataset(
    "glue",
    dataset_config_name="sst2",
    preprocess_function=partial(preprocess_function, tokenizer=tokenizer),
    num_samples=300,
    dataset_split="train",
)
The quantize() method applies post-training static quantization and export the resulting quantized model to the OpenVINO Intermediate Representation (IR). The resulting graph is represented with two files: an XML file describing the network topology and a binary file describing the weights. The resulting model can be run on any target Intel device.

Hybrid quantization
Traditional optimization methods like post-training 8-bit quantization do not work well for Stable Diffusion (SD) models and can lead to poor generation results. On the other hand, weight compression does not improve performance significantly when applied to Stable Diffusion models, as the size of activations is comparable to weights. The U-Net component takes up most of the overall execution time of the pipeline. Thus, optimizing just this one component can bring substantial benefits in terms of inference speed while keeping acceptable accuracy without fine-tuning. Quantizing the rest of the diffusion pipeline does not significantly improve inference performance but could potentially lead to substantial accuracy degradation. Therefore, the proposal is to apply quantization in hybrid mode for the U-Net model and weight-only quantization for the rest of the pipeline components :

U-Net : quantization applied on both the weights and activations
The text encoder, VAE encoder / decoder : quantization applied on the weights
The hybrid mode involves the quantization of weights in MatMul and Embedding layers, and activations of other layers, facilitating accuracy preservation post-optimization while reducing the model size.

The quantization_config is utilized to define optimization parameters for optimizing the SD pipeline. To enable hybrid quantization, specify the quantization dataset in the quantization_config. If the dataset is not defined, weight-only quantization will be applied on all components.

Copied
from optimum.intel import OVStableDiffusionPipeline, OVWeightQuantizationConfig

model = OVStableDiffusionPipeline.from_pretrained(
    model_id,
    export=True,
    quantization_config=OVWeightQuantizationConfig(bits=8, dataset="conceptual_captions"),
)
For more details, please refer to the corresponding NNCF documentation.

Training-time
Apart from optimizing a model after training like post-training quantization above, optimum.openvino also provides optimization methods during training, namely Quantization-Aware Training (QAT) and Joint Pruning, Quantization and Distillation (JPQD).

Training-time optimization methods are deprecated and will be removed in optimum-intel v1.22.0.

Quantization-Aware Training (QAT)
QAT simulates the effects of quantization during training, in order to alleviate its effects on the model’s accuracy. It is recommended in the case where post-training quantization results in high accuracy degradation. Here is an example on how to fine-tune a DistilBERT on the sst-2 task while applying quantization aware training (QAT).

Copied
  import evaluate
  import numpy as np
  from transformers import (
      AutoModelForSequenceClassification,
      AutoTokenizer,
      TrainingArguments,
      default_data_collator,
  )
  from datasets import load_dataset
- from transformers import Trainer
+ from optimum.intel import OVConfig, OVTrainer, OVModelForSequenceClassification

  model_id = "distilbert-base-uncased-finetuned-sst-2-english"
  model = AutoModelForSequenceClassification.from_pretrained(model_id)
  tokenizer = AutoTokenizer.from_pretrained(model_id)
  # The directory where the quantized model will be saved
  save_dir = "qat_model"
  dataset = load_dataset("glue", "sst2")
  dataset = dataset.map(
      lambda examples: tokenizer(examples["sentence"], padding=True), batched=True
  )
  metric = evaluate.load("glue", "sst2")

  def compute_metrics(eval_preds):
      preds = np.argmax(eval_preds.predictions, axis=1)
      return metric.compute(predictions=preds, references=eval_preds.label_ids)

  # Load the default quantization configuration detailing the quantization we wish to apply
+ ov_config = OVConfig()

- trainer = Trainer(
+ trainer = OVTrainer(
      model=model,
      args=TrainingArguments(save_dir, num_train_epochs=1.0, do_train=True, do_eval=True),
      train_dataset=dataset["train"].select(range(300)),
      eval_dataset=dataset["validation"],
      compute_metrics=compute_metrics,
      tokenizer=tokenizer,
      data_collator=default_data_collator,
+     ov_config=ov_config,
+     task="text-classification",
)

  # Train the model while applying quantization
  train_result = trainer.train()
  metrics = trainer.evaluate()
  # Export the quantized model to OpenVINO IR format and save it
  trainer.save_model()

  # Load the resulting quantized model
- model = AutoModelForSequenceClassification.from_pretrained(save_dir)
+ model = OVModelForSequenceClassification.from_pretrained(save_dir)
Joint Pruning, Quantization and Distillation (JPQD)
Other than quantization, compression methods like pruning and distillation are common in further improving the task performance and efficiency. Structured pruning slims a model for lower computational demands while distillation leverages knowledge of a teacher, usually, larger model to improve model prediction. Combining these methods with quantization can result in optimized model with significant efficiency improvement while enjoying good task accuracy retention. In optimum.openvino, OVTrainer provides the capability to jointly prune, quantize and distill a model during training. Following is an example on how to perform the optimization on BERT-base for the sst-2 task.

First, we create a config dictionary to specify the target algorithms. As optimum.openvino relies on NNCF as backend, the config format follows NNCF specifications (see here). In the example config below, we specify pruning and quantization in a list of compression with thier hyperparameters. The pruning method closely resembles the work of Lagunas et al., 2021, Block Pruning For Faster Transformers whereas the quantization refers to QAT. With this configuration, the model under optimization will be initialized with pruning and quantization operators at the beginning of the training.

Copied
compression_config = [
    {
        "compression":
        {
        "algorithm":  "movement_sparsity",
        "params": {
            "warmup_start_epoch":  1,
            "warmup_end_epoch":    4,
            "importance_regularization_factor":  0.01,
            "enable_structured_masking":  True
        },
        "sparse_structure_by_scopes": [
            {"mode":  "block",   "sparse_factors": [32, 32], "target_scopes": "{re}.*BertAttention.*"},
            {"mode":  "per_dim", "axis":  0,                 "target_scopes": "{re}.*BertIntermediate.*"},
            {"mode":  "per_dim", "axis":  1,                 "target_scopes": "{re}.*BertOutput.*"},
        ],
        "ignored_scopes": ["{re}.*NNCFEmbedding", "{re}.*pooler.*", "{re}.*LayerNorm.*"]
        }
    },
    {
        "algorithm": "quantization",
        "weights": {"mode": "symmetric"}
        "activations": { "mode": "symmetric"},
    }
]
Known limitation: Current structured pruning with movement sparsity only supports BERT, Wav2vec2 and Swin family of models. See here for more information.

Once we have the config ready, we can start develop the training pipeline like the snippet below. Since we are customizing joint compression with config above, notice that OVConfig is initialized with config dictionary (JSON parsing to python dictionary is skipped for brevity). As for distillation, users are required to load the teacher model, it is just like a normal model loading with transformers API. OVTrainingArguments extends transformers’ TrainingArguments with distillation hyperparameters, i.e. distillation weightage and temperature for ease of use. The snippet below shows how we load a teacher model and create training arguments with OVTrainingArguments. Subsequently, the teacher model, with the instantiated OVConfig and OVTrainingArguments are fed to OVTrainer. Voila! that is all we need, the rest of the pipeline is identical to native transformers training.

Copied
- from transformers import Trainer, TrainingArguments
+ from optimum.intel import OVConfig, OVTrainer, OVTrainingArguments

  # Load teacher model
+ teacher_model = AutoModelForSequenceClassification.from_pretrained(teacher_model_or_path)

- ov_config = OVConfig()
+ ov_config = OVConfig(compression=compression_config)

  trainer = OVTrainer(
      model=model,
+     teacher_model=teacher_model,
-     args=TrainingArguments(save_dir, num_train_epochs=1.0, do_train=True, do_eval=True),
+     args=OVTrainingArguments(save_dir, num_train_epochs=1.0, do_train=True, do_eval=True, distillation_temperature=3, distillation_weight=0.9),
      train_dataset=dataset["train"].select(range(300)),
      eval_dataset=dataset["validation"],
      compute_metrics=compute_metrics,
      tokenizer=tokenizer,
      data_collator=default_data_collator,
+     ov_config=ov_config,
      task="text-classification",
  )

  # Train the model like usual, internally the training is applied with pruning, quantization and distillation
  train_result = trainer.train()
  metrics = trainer.evaluate()
  # Export the quantized model to OpenVINO IR format and save it
  trainer.save_model()
More on the description and how to configure movement sparsity, see NNCF documentation here.

More on available algorithms in NNCF, see documentation here.

For complete JPQD scripts, please refer to examples provided here.

Quantization-Aware Training (QAT) and knowledge distillation can also be combined in order to optimize Stable Diffusion models while maintaining accuracy. For more details, take a look at this blog post.

Inference with Transformers pipeline
After applying quantization on our model, we can then easily load it with our OVModelFor<Task> classes and perform inference with OpenVINO Runtime using the Transformers pipelines.

Copied
from transformers import pipeline
from optimum.intel import OVModelForSequenceClassification

model_id = "helenai/distilbert-base-uncased-finetuned-sst-2-english-ov-int8"
ov_model = OVModelForSequenceClassification.from_pretrained(model_id)
tokenizer = AutoTokenizer.from_pretrained(model_id)
cls_pipe = pipeline("text-classification", model=ov_model, tokenizer=tokenizer)
text = "He's a dreadful magician."
outputs = cls_pipe(text)

[{'label': 'NEGATIVE', 'score': 0.9840195178985596}]




So I want you to use it to optemize my code I have already exported the two models to OpenVINO using their hugging face space and here is their links:

https://huggingface.co/BFM007/wav2vec2-large-robust-12-ft-emotion-msp-dim-openvino
https://huggingface.co/BFM007/wav2vec2-base-finetuned-sentiment-classification-MESD-openvino