Ana içeriğe geç

Mistral’ın Voxtral’ı: Demo Projeyle Rehber

Mistral’ın Voxtral Mini 3B modelini vLLM ile çalıştırmayı, bir API kurmayı ve Streamlit tabanlı bir ses özetleyici ve S&C uygulaması geliştirmeyi öğrenin.
· 12 dk. oku

Yapay Zeka ile Keşfedin

Mistral kısa süre önce, Mistral 3B mimarisi üzerine inşa edilen ve özellikle ses anlama ile deşifre görevleri için optimize edilen, ilk açık kaynak çok modlu ses modelleri Voxtral Small ve Voxtral Mini’yi yayımladı.

Bu blogda odağım Voxtral Mini 3B olacak: deşifre, özetleme ve S&C gibi gerçek zamanlı sesten metne görevler için tasarlanmış, kompakt ve açık kaynaklı bir model. Verimli boyutu ve uzun bağlam akıl yürütme desteğiyle Voxtral Mini, vLLM gibi yüksek verimlilikli çıkarım çerçeveleriyle eşleştirildiğinde özellikle güçlüdür ve hızlı, çevrimdışı ses uygulamaları oluşturmak için idealdir.

Bu eğitimde şunları adım adım göstereceğim:

  • Colab Pro üzerinde vLLM ile Voxtral Mini 3B’yi çalıştırma
  • Modelinize her yerden erişmek için ngrok tünelli bir API uç noktası dağıtma
  • Ham ses girdisi kullanarak deşifre, özetleme ve S&C yapan Streamlit tabanlı bir ses asistanı geliştirme

Okurlarımızı yapay zekâdaki en güncel gelişmelerden haberdar etmek için, haftanın önemli haberlerini özetleyen ücretsiz Cuma bültenimiz The Median’i gönderiyoruz. Abone olun; haftada sadece birkaç dakikada güncel kalın:

Mistral’ın Voxtral’ı Nedir?

Voxtral, güçlü konuşma anlama için tasarlanmış, Mistral’ın tamamen açık kaynaklı ses modeli ailesidir. Voxtral iki model boyutuyla gelir:

  • Voxtral Small: 24 B parametre, üretim ölçeğinde kurumsal kullanım için ideal
  • Voxtral Mini: 3 B parametre, uç cihazlarda yerel çalıştırma için optimize edilmiştir

mistral's voxtral benchmarks

Kaynak: Mistral

Voxtral, ham ses girdilerini (örn. .wav veya .mp3) kabul eder ve konuşulan içerikten verimli şekilde deşifre ve özet üretmek üzere eğitilmiştir. Voxtral, hızlı çıkarım ve çevrimdışı dağıtım için optimize edilmiş daha küçük bir varyanttır.

Mistral’ın model biçimini takip eder ve vLLM gibi yüksek verimlilikli çıkarım çerçeveleriyle uyumludur; bu da onu gerçek zamanlı deşifre veya hafif konuşma uygulamaları için mükemmel bir seçenek yapar.

Voxtral Mini 3B vLLM Kullanılarak Nasıl Çalıştırılır

Bu bölümde, T4 GPU etkin bir Colab Pro üzerinde vLLM kullanarak Voxtral Mini 3B’yi nasıl sunacağınızı göstereceğim. vLLM, ses desteğiyle hızlı akış yanıtları gerektiren Voxtral gibi modeller için ideal olan yüksek verimlilik ve düşük gecikmeli sunum kabiliyetleri nedeniyle seçildi.

Ek olarak, vLLM sunucusunu genel bir uç nokta üzerinden açığa çıkarmak ve yerel makinenizde çalışan uygulamaların erişebilmesini sağlamak için PyNGrok kullanacağız.

Adım 1: Bağımlılıkları yükleyin

Colab ortamımızda bağımlılıkları yükleyerek başlayalım. Aşağıdaki komutu Colab hücresinde çalıştırın:

!uv pip install -U transformers accelerate "vllm[audio]" --torch-backend=auto --extra-index-url https://wheels.vllm.ai/nightly

Gerekli kütüphaneleri daha hızlı bir Python paket yükleyicisi olan uv kullanarak kuruyoruz. Bu, Voxtral gibi ses-dil modelleri için deneysel destek içeren vllm[audio]’nun gecelik sürümünü getirir. Ortamınızda uv yüklü değilse, önce aşağıdaki kodu çalıştırarak uv kurun:

!pip install uv

Adım 2: Mistral-Common’ı yükleyin

Sonraki adımda, Voxtral ve diğer Mistral ailesi modellerle etkileşim için gerekli yardımcı araçları sağlayan mistral-common paketini kuruyoruz. Bu paket, resmi uygulamalarla hizalı belirteçleyiciler (tokenizer’lar) ve mesaj yapıları için Pydantic tabanlı doğrulama içerir.

!pip install mistral-common --upgrade
!python -c "import mistral_common; print(mistral_common.__version__)"

mistral-common paketi, Voxtral ve diğer Mistral ailesi modeller için yardımcı modüller içerir. Tokenizer’lar, Pydantic formatlarında tipli mesajlar ve ses yardımcı işlevleri barındırır. Bu adım, Voxtral’ın ses girdileri ve yapılandırılmış mesajları dahili olarak işleyişiyle uyumu sağlar.

Adım 3: VLLM’i kurun

Temel Mistral bağımlılıklarını hazırladığımıza göre, şimdi ana deposunu klonlayarak vLLM’i kuruyoruz.

Adım 3.1: vLLM deposunu klonlayın

Yerleşik ses örneklerine erişim sağlayan ve çevrimdışı ya da barındırılan çıkarımı başlatmak için temel görevi gören resmi vLLM GitHub deposunu klonluyoruz.

!git clone https://github.com/vllm-project/vllm && cd vllm

Adım 3.2: Örnek bir ses çıkarımı çalıştırın 

Kurulumun doğru olduğundan emin olmak için hızlı bir doğrulama çalıştıralım.

!python vllm/examples/offline_inference/audio_language.py --num-audios 2 --model-type voxtral

Voxtral modelini kullanarak iki ön tanımlı örnek üzerinde ses-dil çıkarımı yapan ve ses çözme ile üretimin düzgün çalıştığını doğrulayan çevrimdışı audio_language.py örneğini çalıştırdım.

Adım 4: PyGrok’u kurun

vLLM hazır olduğuna göre, vLLM sunucusunu Colab üzerinde genel olarak erişilebilir bir internet adresiyle açığa çıkarmak için PyNGrok’u yapılandıralım.

  • Önce https://ngrok.com/ adresinde ücretsiz bir hesap oluşturun
  • Connect sekmesinde aşağı kaydırıp kimlik doğrulama etiketini (aşağıdaki görselde gizli) kopyalayın ve bunu Colab Secrets içine bir gizli anahtar olarak kaydedin.

NGrok Token

Ardından, Colab ortamında PyNGrok’u kurup daha önce kopyaladığımız NGROK belirteciyle kimlik doğrulama jetonunu ayarlıyoruz. Bir prototip üzerinde çalışıyorsanız, belirteci doğrudan burada iletebilirsiniz.

!pip install pyngrok -q
from pyngrok import ngrok
ngrok.set_auth_token("NGROK_TOKEN")

Adım 5: Modeli servis edin

Burası kilit adım: Voxtral Mini 3B modelini vLLM üzerinden başlatacağız. 

!vllm serve mistralai/Voxtral-Mini-3B-2507 --tokenizer_mode mistral --config_format mistral --load_format mistral --max-model-len 4864

Kod parçası birkaç önemli bayrak içerir:

  • --tokenizer_mode mistral: Doğru biçimleme için Mistral’a özgü tokenizer kullanılır.
  • --config_format mistral ve --load_format mistral: Bu bayraklar, model yapılandırması ve ağırlıklarının Mistral’ın özel biçiminde yüklenmesini sağlar; uyumluluğu korur.
  • --max-model-len 4864: En fazla giriş bağlam uzunluğunu 4864 belirteç olarak ayarlar.

Not: Bu hücreyi çalışır durumda tutun; bu, etkin bir model sunucusudur.

Adım 6: NGrok genel uç noktasını alın

vLLM sunucunuz çalışır durumdayken, aşağıdaki kodu bir Python terminalinde satır satır çalıştırın:

from pyngrok import ngrok
ngrok.set_auth_token(NGROK_TOKEN)
public_url = ngrok.connect(8000)
print("Public endpoint:", public_url)

Yukarıdaki kod, modeli internete geçici bir genel URL üzerinden açığa çıkaracaktır; örneğin:

https://80xxxxxxxxxx.ngrok-free.app

Bu URL’yi kaydedin; uzaktaki modele bağlanmak için yerel config.py içinde kullanılacaktır. Çalıştırma tamamlandıktan sonra bağlantıyı şu komutla sonlandırın:

ngrok.kill()

Bir Ses Deşifre ve Özetleme Demosu Oluşturma

Bu bölümde, aşağıdakileri yapan bir Streamlit arayüzü geliştireceğiz:

  1. Girdi olarak ses alır (kullanıcı yüklemesi)
  2. vLLM sunucusu üzerinden modele gönderir
  3. Deşifreyi, özeti görüntüler ve kullanıcının soru sormasına olanak tanır

Adım 1: Bağımlılıkları ayarlama

Uygulamayı oluşturmadan önce tüm gerekli bağımlılıkları bir requirements.txt dosyasında tanımlarız. Bu, yerel çalıştırmalar veya Colab defterleri arasında tutarlı ortamlar sağlar.

streamlit>=1.28.0
openai>=1.0.0
mistral-common>=0.0.12
huggingface-hub>=0.19.0
pyngrok>=6.0.0
requests>=2.28.0
pydub>=0.25.1 

Her birine neden ihtiyaç duyduğumuz:

  • streamlit: Etkileşimli ses arayüzünü oluşturmaya yardımcı olur.
  • openai: OpenAI SDK’sını kullanarak Voxtral uyumlu vLLM sunucusuyla iletişim kurar.
  • mistral-common: AudioChunk ve TextChunk gibi Voxtral’a özgü yardımcılar sağlar.
  • pyngrok: Yerel vLLM sunucumuzu internete açar; böylece Streamlit uygulaması erişebilir.
  • Pydub: Çıkarım için ses dosyalarını dönüştürmeye yardımcı olur.
  • huggingface-hub ve requests: Model ve yapılandırma çekme (gerekirse) için kullanılır.

Adım 2: Ortam değişkenini ayarlama

Yapılandırmayı temiz ve taşınabilir tutmak için API ayrıntılarını ortam değişkenleri olarak saklarız. Bunları bir .env dosyasında tanımlayabilirsiniz:

VOXTRAL_API_KEY=dummy-key
VOXTRAL_API_BASE=NGROK_TOKEN/v1
VOXTRAL_MODEL_NAME=mistralai/Voxtral-Mini-3B-2507

VOXTRAL_API_BASE, çalışan vLLM örneğinizi işaret etmelidir; bu, localhost (http://localhost:8000) ya da https://80xxxxxxxxxx.ngrok-free.app gibi bir ngrok genel uç noktası olabilir.

Not: OpenAI uyumluluğu için API tabanının sonuna /v1 eklediğinizden emin olun.

Adım 3: Yapılandırma dosyasını ayarlama

Uygulamanızı modüler, kolay ayarlanabilir ve üretime hazır yapmak için config.py içinde merkezi bir yapılandırma sınıfı tanımlayacağız. Bu dosya, model ayarlarını, API erişimini, desteklenen ses formatlarını, dilleri ve arayüz tercihlerini kontrol edecek.

Adım 3.1: Ortam değişkenlerini yükleyin

Yapılandırma sınıfını tanımlamadan önce, bir .env dosyasına kaydedilen ortam değişkenlerini yüklüyoruz. Bu, hassas bilgilerin koddan ayrı tutulmasını sağlar.

import os
from typing import Optional
from pathlib import Path
# Load environment variables from .env file
env_file = Path(".env")
if env_file.exists():
    with open(env_file, 'r') as f:
        for line in f:
            if line.strip() and not line.startswith('#'):
                key, value = line.strip().split('=', 1)
                os.environ[key] = value

Bu kod, kök dizinde bir .env dosyası olup olmadığını denetler. Bulursa, anahtar-değer çiftlerini okuyup ortam değişkeni olarak ayarlar. Bu değerlere artık os.getenv() kullanılarak erişilebilir; böylece gizli bilgiler uygulamaya gömülmez.

Adım 3.2: Config sınıfını tanımlayın

Şimdi tüm ayarları, kolay erişim ve yeniden kullanım için temiz bir Config sınıfında topluyoruz.

class Config:
    # API Configuration
    VOXTRAL_API_KEY: str = os.getenv("VOXTRAL_API_KEY", "EMPTY")
    VOXTRAL_API_BASE: str = os.getenv("VOXTRAL_API_BASE", "http://localhost:8000/v1")
    # Model Configuration
    MODEL_NAME: str = os.getenv("VOXTRAL_MODEL_NAME", "voxtral-mini-3b-2507")
    # Default Parameters
    DEFAULT_TEMPERATURE: float = 0.2
    DEFAULT_TOP_P: float = 0.95
    # Audio Configuration
    MAX_AUDIO_SIZE_MB: int = 100
    SUPPORTED_AUDIO_FORMATS: list = ['mp3', 'wav', 'm4a', 'flac', 'ogg']
    SUPPORTED_LANGUAGES: list = [
        "English", "Spanish", "French", "German", "Italian", "Portuguese", 
        "Russian", "Chinese", "Japanese", "Korean", "Arabic", "Hindi"
    ]
    # UI Configuration
    STREAMLIT_THEME: dict = {
        "primaryColor": "#1f77b4",
        "backgroundColor": "#ffffff",
        "secondaryBackgroundColor": "#f0f2f6",
        "textColor": "#262730",
        "font": "sans serif"
    }
    @classmethod
    def get_api_config(cls) -> dict:
        return {
            "api_key": cls.VOXTRAL_API_KEY,
            "base_url": cls.VOXTRAL_API_BASE,
            "model_name": cls.MODEL_NAME
        }    
    @classmethod
    def validate_config(cls) -> bool:
        if not cls.VOXTRAL_API_BASE:
            return False
        return True    
    @classmethod
    def get_language_code(cls, language_name: str) -> Optional[str]:
        language_mapping = {
            "English": "en",
            "Spanish": "es", 
            "French": "fr",
            "German": "de",
            "Italian": "it",
            "Portuguese": "pt",
            "Russian": "ru",
            "Chinese": "zh",
            "Japanese": "ja",
            "Korean": "ko",
            "Arabic": "ar",
            "Hindi": "hi"
        }
        return language_mapping.get(language_name) 

Birlikte ele alındığında bu Config sınıfı, Voxtral destekli uygulamanız için merkezi kontrol merkezi görevi görür. İster model parametrelerini yapılandırıyor, ister ses formatlarını yönetiyor, ister uygulama temasını ayarlıyor olun; bu kurulum temiz soyutlama, kodun yeniden kullanılabilirliği ve sürdürülebilirlik sağlar.

Sınıf şunları içerir:

  • get_api_config() yöntemi: Tüm API ile ilgili kimlik bilgilerini merkezileştirir. Uygulamanız Voxtral modeline çağrı yaptığında, tek seferde gereken her şeyi almak için Config.get_api_config() kullanabilirsiniz.
  • validate_config() yöntemi: Çıkarıma başlamadan önce, temel URL gibi kritik yapılandırma değerlerinin düzgün tanımlandığını doğrulamanıza olanak tanır. Aksi durumda sorunu erken yakalayıp kullanıcıyı uyarabilirsiniz.
  • get_language_code() yöntemi: Kullanıcı dostu dil adlarını (örn. “French”) standart ISO dil kodlarına (örn. “fr”) eşleyerek çok dilli S&C’yi kolaylaştırır. Desteklenmeyen bir dil iletilirse güvenli şekilde None döndürür.

Adım 4: Streamlit uygulamasını oluşturun

Uygulama arayüzünü ve mantığını oluşturan her alt adımı birlikte inceleyelim.

Adım 4.1: Düzeni ve stili ayarlayın

Bu adımda, Streamlit ön yüzünü başlatıyor, bağımlılıkları yüklüyor ve CSS stilini kuruyoruz. Bu, uygulamanın görsel ve işlevsel temelini oluşturur.

import streamlit as st
import tempfile
import os
from mistral_common.protocol.instruct.messages import TextChunk, AudioChunk, UserMessage
from mistral_common.audio import Audio
from openai import OpenAI
import time
from config import Config
# Page configuration
st.set_page_config(
    page_title="Voxtral Audio Assistant",
    page_icon="🎵",
    layout="wide",
    initial_sidebar_state="expanded"
)
# Custom CSS 
st.markdown("""
<style>
    .main-header {
        
        font-weight: bold;
        
        text-align: center;
        
    }
    .section-header {
        
        font-weight: bold;
        
        
    }
    .info-box {
        background-
        
        border-radius: 0.5rem;
        border-left: 4px solid #1f77b4;
        
    }
    .success-box {
        background-
        
        border-radius: 0.5rem;
        border-left: 4px solid #28a745;
        
    }
    .chat-message {
        
        border-radius: 0.5rem;
        
    }
    .user-message {
        background-
        border-left: 4px solid #2196f3;
    }
    .assistant-message {
        background-
        border-left: 4px solid #9c27b0;
    }
</style>
""", unsafe_allow_html=True)

Yukarıdaki Python ve CSS kodunda:

  • UI, dosya yönetimi ve Voxtral’ın mistral_common paketini kullanarak ses/metin mesaj biçimlendirme için temel kütüphaneleri içe aktarıyoruz.
  • Ardından, varsayılan olarak genişletilmiş bir kenar çubuğu içeren, çift panelli bir düzenle Streamlit uygulamasının yerleşimini yapılandırıyoruz.
  • Son olarak, başlıklar, ses bölümleri, sohbet balonları ve özet kutuları gibi UI parçalarını görsel olarak ayırmak için özel CSS ekliyoruz. Bu, kullanıcı ve asistan yanıtları için farklı sohbet balonları ve stilli başlıklar ile bilgi iletileriyle görsel hiyerarşiyi iyileştirir.

Adım 4.2: Oturumu ve istemciyi başlatın

Sonraki adımda, oturum değişkenlerini ve istemciyi başlatarak uygulamanın yeniden yüklemeler arasında tutarlı davranmasını sağlıyoruz.

def init_session_state():
    defaults = {
        'transcription': "",
        'summary': "",
        'chat_history': [],
        'audio_file_path': None
    }
    for key, default_value in defaults.items():
        if key not in st.session_state:
            st.session_state[key] = default_value
def initialize_client():
    config = Config.get_api_config() 
    client = OpenAI(
        api_key=config["api_key"],
        base_url=config["base_url"],
    ) 
    # Test connection
    try:
        models = client.models.list()
        return client
    except Exception as e:
        st.error(f"Failed to connect to Voxtral API: {str(e)}")
        st.info("Make sure your ngrok tunnel is running in Google Colab")
        return None

Bu kod parçası, uygulamanın dahili durumunu kurar ve Voxtral API sunucusuna bağlantıyı yönetir. İki temel bileşen içerir:

  1. Oturum başlatma: Deşifreler, özetler ve yüklenen ses dosyaları gibi kullanıcı verilerinin, etkileşimler ve yeniden yüklemeler arasında doğru şekilde var olmasını sağlar.
  2. İstemci başlatma: Ngrok üzerinden sunulan, OpenAI uyumlu uç nokta aracılığıyla yerelde barındırılan Voxtral Mini 3B modeline bağlanır. Bağlantı başarısız olursa, UI’da bir hata iletisi gösterilir.

Adım 4.3: Ses parçalara ayırma ve gerçek zamanlı deşifre

Bu adım, ses dosyasını hazırlama ve Voxtral Mini 3B kullanarak bir deşifre oluşturma işinin özünü ele alır.

def file_to_chunk(file_path: str) -> AudioChunk:
    audio = Audio.from_file(file_path, strict=False)
    return AudioChunk.from_audio(audio)
def transcribe_audio(client, audio_file_path):
    try:
        with open(audio_file_path, "rb") as f:
            response = client.audio.transcriptions.create(
                file=f,
                model=Config.MODEL_NAME,
                response_format="text",
                stream=True
            )       
            transcription = ""
            progress_bar = st.progress(0)
            status_text = st.empty()
            # Collect all chunks first to get total count
            chunks = list(response)
            total_chunks = len(chunks)
            for i, chunk in enumerate(chunks):
                delta = chunk.choices[0].get("delta", {}).get("content")
                if delta:
                    transcription += delta
                    progress = min((i + 1) / max(total_chunks, 1), 1.0)
                    progress_bar.progress(progress)
                    status_text.text(f"Transcribing... {len(transcription)} characters")
            progress_bar.empty()
            status_text.empty()
            return transcription
    except Exception as e:
        st.error(f"Error during transcription: {str(e)}")
        return None

Burada iki temel işlev bulunur:

  1. Ses parça dönüşümü: Önce, yüklenen ses dosyasını Voxtral’ın API gereksinimi olan AudioChunk biçimine dönüştürüyoruz.
  2. İlerleme geri bildirimiyle akışlı deşifre: Sesi modele akışlı olarak gönderiyor (stream=True) ve parçaları tek tek çözüyoruz. Alınan belirteçlerle birlikte bir ilerleme çubuğu dinamik olarak güncellenir ve kullanıcılara deşifre ilerleyişine dair gerçek zamanlı geri bildirim verir.

Adım 4.4: Sesten özet üretin

Bu adım, ses girdisini metinsel bir istemle birlikte Voxtral modeline gönderir ve ses içeriğinin kısa ve yapılandırılmış bir özetini döndürür.

def generate_summary(client, audio_file_path):
    try:
        audio_chunk = file_to_chunk(audio_file_path)
        text_chunk = TextChunk(text="Please provide a comprehensive summary of this audio content, highlighting the key points and main themes discussed.")
        user_msg = UserMessage(content=[audio_chunk, text_chunk]).to_openai()    
        response = client.chat.completions.create(
            model=Config.MODEL_NAME,
            messages=[user_msg],
            temperature=Config.DEFAULT_TEMPERATURE,
            top_p=Config.DEFAULT_TOP_P,
        )
        return response.choices[0].message.content
    except Exception as e:
        st.error(f"Error generating summary: {str(e)}")
        return None

Yukarıdaki kod, yüklenen sesten özet üretmek için birkaç temel yöntem ve işlev kullanır:

  • audio_chunk: Önce, yüklenen ses dosyasını Voxtral’ın ses işleme süreci için bir AudioChunk’a dönüştürürüz.
  • text_chunk: Ardından, içeriğin net ve kapsamlı şekilde özetlenmesi için modeli yönlendiren bir metin istemi kullanılır.
  • UserMessage: Bu, audio_chunk ve text_chunk’ı OpenAI uyumlu tek bir çok modlu mesaja birleştirir. 
  • Response.choices[0].message.content: Bu nesne, modelin yanıtındaki gerçek özet metnini çıkarır.

Adım 4.5: Ses üzerinde çok dilli S&C

Artık özetimiz var. Yüklenen ses içeriği hakkında doğal dilde sorular sorulmasını sağlayalım. Bu, sesi metin istemlerle birleştirerek bağlama duyarlı yanıtlar üretmek için Voxtral’ın çok modlu yeteneklerini kullanır.

Aşağıdaki işlev, seçilen dile göre istemi dinamik olarak değiştirerek çok dilli yanıtları da destekler.

def ask_question(client, audio_file_path, question, language="English"):
    try:
        audio_chunk = file_to_chunk(audio_file_path)
        if language != "English":
            question = f"Please answer the following question in {language}: {question}"
        text_chunk = TextChunk(text=question)
        user_msg = UserMessage(content=[audio_chunk, text_chunk]).to_openai()        
        response = client.chat.completions.create(
            model=Config.MODEL_NAME,
            messages=[user_msg],
            temperature=Config.DEFAULT_TEMPERATURE,
            top_p=Config.DEFAULT_TOP_P,
        )        
        return response.choices[0].message.content
    except Exception as e:
        st.error(f"Error asking question: {str(e)}")
        return None

Yukarıdaki kodda neler olduğunun özeti:

  • ask_question() işlevi, kullanıcıların yüklenen ses hakkında herhangi bir soru sormasına olanak tanır.
  • Önce, yeniden kullanılabilir file_to_chunk() işlevini kullanarak yüklenen dosyayı bir AudioChunk’a dönüştürür; bu, sesi Voxtral’ın çok modlu API’sinin beklediği biçime hazırlar.
  • Sonra seçilen dili denetler. İngilizce değilse, kullanıcının sorusuna istenen dilde yanıt verilmesini isteyen bir yönerge eklenir (ör. Hintçe veya İspanyolca).
  • Kullanıcının sorusu bir TextChunk içine alınır; hem ses hem de metin çok modlu bir UserMessage içinde paketlenir.
  • Bu mesajı, üretim kalitesini kontrol etmek için yapılandırmadan gelen sıcaklık ve top-p değerleriyle birlikte modele göndeririz.
  • Model, tek turluk bir yanıt döndürür.

Adım 4.6: Kenar çubuğunu ayarlayın

Kenar çubuğu, oturum ayarlarını yönetmeye, çıktı dilini seçmeye, Voxtral API bağlantısını test etmeye ve sezgisel kaydırıcılarla modelin yanıt davranışını özelleştirmeye olanak tanıyan bir kontrol paneli işlevi görür.

def render_sidebar():
    with st.sidebar:
        st.markdown('<h3 class="section-header">Configuration</h3>', unsafe_allow_html=True)        
        # Connection status
        st.markdown('<h4>Connection Status</h4>', unsafe_allow_html=True)
        if st.button("Test Connection"):
            client = initialize_client()
            if client:
                st.success("Connected to Voxtral API")
            else:
                st.error("Connection failed")        
        # Language selection
        selected_language = st.selectbox("Select language for Q&A:", Config.SUPPORTED_LANGUAGES)        
        # Model configuration
        st.markdown('<h4>Model Settings</h4>', unsafe_allow_html=True)
        temperature = st.slider("Temperature", 0.0, 1.0, Config.DEFAULT_TEMPERATURE, 0.1)
        top_p = st.slider("Top P", 0.0, 1.0, Config.DEFAULT_TOP_P, 0.05)
        if st.button("Clear Session"):
            for key in ['transcription', 'summary', 'chat_history', 'audio_file_path']:
                st.session_state[key] = "" if key in ['transcription', 'summary'] else [] if key == 'chat_history' else None
            st.rerun()        
        return selected_language, temperature, top_p

Kodun ayrımı:

  • Kenar çubuğu: st.sidebar, uygulama için yapılandırma araçlarını sakladığımız açılır bir kenar çubuğunu açar.
  • Bağlantı testi: "Test Connection" düğmesi, Voxtral API’ye bağlanmayı deneyen initialize_client() işlevini tetikler ve Streamlit uyarılarıyla başarı veya başarısızlığı bildirir.
  • Dil seçimi: 12 desteklenen dilden birini seçmenizi sağlayan bir açılır menü. Bu seçim, modelin o dilde yanıt vermesini sağlar.
  • Model parametreleri: Kullanıcının şu model parametrelerini kontrol etmesine izin veren kaydırıcılar:
    • temperature: Yaratıcılığı kontrol eder. Düşük değerler yanıtları daha belirleyici, yüksek değerler daha çeşitli yapar.
    • top_p: En olası belirteçlerle üretimi sınırlandırmaya yardımcı olan çekirdek örneklemeyi (nucleus sampling) kontrol eder.
  • Oturumu temizle: "Clear Session" düğmesi, tüm oturum durumu değişkenlerini sıfırlar ve uygulamayı yeniden çalıştırır.

Adım 4.7: Ses yükleme ve işleme bölümü

Bu bölüm, kullanıcıların (.mp3, .wav vb.) ses dosyalarını yüklemesine ve bunların geçici olarak kaydedilmesine olanak tanır. Yüklendikten sonra kullanıcılar, sesi deşifre etmeyi veya üst düzey bir özet oluşturmayı seçebilir.

def render_audio_processing():
    st.markdown('<h3 class="section-header">Audio Upload & Processing</h3>', unsafe_allow_html=True)    
    uploaded_file = st.file_uploader(
        "Choose an audio file",
        type=Config.SUPPORTED_AUDIO_FORMATS,
        help="Upload an audio file to transcribe and analyze"
    )
    if uploaded_file is not None:
        with tempfile.NamedTemporaryFile(delete=False, suffix=f".{uploaded_file.name.split('.')[-1]}") as tmp_file:
            tmp_file.write(uploaded_file.getvalue())
            st.session_state.audio_file_path = tmp_file.name
        st.success(f"File uploaded: {uploaded_file.name}")
        # Initialize client
        client = initialize_client()
        col1, col2 = st.columns(2) 
        with col1:
            if st.button("Generate Summary", type="primary"):
                with st.spinner("Generating summary..."):
                    summary = generate_summary(client, st.session_state.audio_file_path)
                    if summary:
                        st.session_state.summary = summary
        with col2:
            if st.button("Transcribe Audio", type="secondary"):
                with st.spinner("Transcribing audio..."):
                    transcription = transcribe_audio(client, st.session_state.audio_file_path)
                    if transcription:
                        st.session_state.transcription = transcription
        if st.session_state.summary:
            st.markdown('<h4>Summary</h4>', unsafe_allow_html=True)
            st.markdown(f'<div class="success-box">{st.session_state.summary}</div>', unsafe_allow_html=True)
        if st.session_state.transcription:
            st.markdown('<h4>Audio Transcription</h4>', unsafe_allow_html=True)
            st.text_area("Transcription", st.session_state.transcription, height=200, label_visibility="collapsed")

Kullanıcı etkileşimleri boyunca kolay ses yükleme, işleme ve sonuçların kalıcı saklanması için modüler bir yapıya ihtiyaç duyuyoruz. Bunu şöyle yaptım:

  • Dosya yükleyici: İlk olarak, Config.SUPPORTED_AUDIO_FORMATS içinde tanımlı birden çok ses biçimini kabul eden bir sürükle-bırak dosya yükleyiciye ihtiyaç var. Dosya yüklendiğinde geçici bir dosyaya yazılır ve st.session_state.audio_file_path içine kaydedilir.
  • İstemci başlatma: Özet ve deşifre çağrıları yapabilmek için Voxtral uyumlu bir istemci başlatılır.
  • Özet ve deşifre düğmeleri: Ardından iki düğme tanımlarız:
    • Özet oluştur: Tıklandığında, yüklenen sesi bir özet istemiyle birlikte modele gönderir. Bir ilerleme göstergesi (spinner) gösterilir; başarılı olursa çıktı st.session_state.summary içine kaydedilir.
    • Sesi deşifre et: Bu düğme ses dosyasını deşifre uç noktasına gönderir. Gerçek zamanlı ilerleme bir spinner ile gösterilir ve sonuç st.session_state.transcription içinde saklanır.
  • Son olarak her iki sonuç da bir metin alanında gösterilir.

Adım 4.8: Etkileşimli çok dilli S&C

Bu adım, kullanıcıların yüklenen ses hakkında birden çok dilde (örn. İngilizce, Hintçe, İspanyolca) soru sormasını sağlar. Seçilen dil, modelin yanıtının biçimlendirilmesinde kullanılır; her soru-cevap çifti oturum tarafından yönetilen bir konuşma geçmişine kaydedilir ve sohbet balonlarıyla gösterilir.

def render_qa_section(selected_language):
    st.markdown('<h3 class="section-header">Multilingual Q&A</h3>', unsafe_allow_html=True) 
    if st.session_state.audio_file_path:
        st.markdown(f'<div class="info-box">Selected language: <strong>{selected_language}</strong></div>', unsafe_allow_html=True)
        question = st.text_input(
            f"Ask a question about the audio (in {selected_language}):",
            placeholder="e.g., What is the main topic discussed?"
        )    
        if st.button("Ask Question", type="primary") and question:
            client = initialize_client()
            with st.spinner("Processing your question..."):
                answer = ask_question(client, st.session_state.audio_file_path, question, selected_language)
                if answer:
                    # Chat history
                    st.session_state.chat_history.append({
                        "question": question,
                        "answer": answer,
                        "language": selected_language,
                        "timestamp": time.strftime("%H:%M:%S")
                    })
                    st.success("Question answered!")
                else:
                    st.error("Failed to get answer. Please try again.")
                if st.session_state.chat_history:
            st.markdown('<h4>Conversation History</h4>', unsafe_allow_html=True)
            for chat in reversed(st.session_state.chat_history):
                st.markdown(f'<div class="chat-message user-message"><strong>Question:</strong> {chat["question"]}</div>', unsafe_allow_html=True)
                st.markdown(f'<div class="chat-message assistant-message"><strong>Answer:</strong> {chat["answer"]}</div>', unsafe_allow_html=True)
                st.markdown("---")
    else:
        st.markdown('<div class="info-box">Please upload an audio file to start asking questions.</div>', unsafe_allow_html=True)

Yukarıdaki kod parçasında neler olduğunun ayrımı:

  • Ask Question düğmesi: Bir metin girişi alanı, kullanıcının seçilen dilde bir soru yazmasına ve Ask Question düğmesine tıklamasına olanak tanır. Tıklandığında şöyle yapar:
    • Voxtral uyumlu istemciyi başlatır.
    • Soruyu, yüklenen sesle birlikte modele gönderir.
    • Model yanıtını beklerken bir spinner gösterir.
  • Yanıt işleme: Yanıt alınırsa şu işlemler yapılır:
    • st.session_state.chat_history içine zaman damgasıyla kaydedilir.
    • Önceden tanımlı özel CSS ile role özgü biçimlendirmeyle (kullanıcı vs. asistan balonu) sunulur.
    • Model başarısız olursa açık bir hata mesajı gösterilir.
  • Konuşma geçmişi: Önceki S&C çiftleri varsa, ters kronolojik sırayla bir ayırıcıyla gösterilir.

Adım 4.9: Uygulamayı başlatma

Bu son adım, oturum durumunun başlatılması, kenar çubuğunun render edilmesi, ses yükleme, deşifre, özet ve iki sütunlu bir düzen kullanılarak S&C dahil olmak üzere daha önce tanımlanan tüm bileşenleri bir araya getirir.

Sunucu çalışırken ve tüm bağımlılıklar yüklüyken, bu adım uygulamanın Streamlit aracılığıyla tarayıcıya sunulmasını ve etkileşime hazır olmasını sağlar.

def main():
    st.markdown('<h1 class="main-header">🎵 Voxtral Audio Assistant</h1>', unsafe_allow_html=True)
    # Initialize session state
    init_session_state()
    # Render sidebar and get configuration
    selected_language, temperature, top_p = render_sidebar()
    col1, col2 = st.columns([1, 1]) 
    with col1:
        render_audio_processing()
    with col2:
        render_qa_section(selected_language)
    st.markdown("---")
    st.markdown("""
    <div style="text-align: center;">
        <p>Powered by <strong>Voxtral Mini 3B</strong> | Built with Streamlit</p>
        <p>Supports multiple languages for audio analysis and Q&A</p>
    </div>
    """, unsafe_allow_html=True)
if __name__ == "__main__":
    main() 

main() işlevi, uygulamanın giriş noktasıdır. Düzeni kontrol eder, render işlemine orkestrasyon sağlar ve tüm oturum değişkenleri ile UI bileşenlerinin düzgün şekilde başlatıldığından emin olur. Yukarıda tanımlanan işlevlerin özeti:

  • init_session_state(): transcription, summary ve chat_history gibi varsayılan değerleri hazırlayarak uygulama durumunun etkileşimler boyunca korunmasını sağlar.
  • render_sidebar(): Dil seçici, bağlantı testi ve model parametreleri dahil yapılandırma bileşenlerini yükler.
  • render_audio_processing(): Kullanıcıların deşifre ve özet üretimi için ses dosyaları yüklemesini ve işlemesini sağlar.
  • render_qa_section(): Son olarak, yüklenen ses üzerinde çok dilli soru-cevap özelliğini etkinleştirir.

Her şey hazır olduğunda uygulamayı şu komutla çalıştırın:

pip install -r requirements.txt

config.py içindeki VOXTRAL_API_BASE ile belirtilen URL üzerinden erişilebilir olduğundan emin olun. Tüm bağımlılıklar yüklendikten sonra, Streamlit uygulamasını terminalde şu komutla çalıştırın:

streamlit run app.py

Tarayıcınız arayüzü otomatik olarak açacaktır. Uygulama artık Voxtral Mini 3B tarafından desteklenen ses yükleme, gerçek zamanlı deşifre, özetler ve çok dilli S&C ile tamamen işlevsel.

Burada ele aldığımız tüm kodları, kurduğum şu GitHub deposunda bulabilirsiniz.

Sonuç

Voxtral Mini 3B, konuşma deşifre ve anlama için verimli, açık ağırlıklı bir modeldir. Bu eğitimde, modeli vLLM ile çalıştırdık, bir API kurduk ve Streamlit kullanarak bir ses özetleyici uygulaması geliştirdik.

Bir podcast özetleyici, toplantı asistanı ya da sesli komut uygulaması geliştiriyor olun; Voxtral Mini, hızlı ve yerel ses akıl yürütme için temel olarak hizmet edebilir.

Aashi Dutt

Yazar

Aashi Dutt

ML (Üretken Yapay Zekâ) alanında Google Developers Uzmanıyım, Kaggle 3x Expert unvanına sahibim ve 3+ yıllık teknoloji deneyimiyle Women Techmakers Elçisiyim. 2020'de bir sağlık teknolojileri girişiminin kurucu ortağı oldum ve Georgia Tech'te makine öğrenmesi alanında uzmanlaşarak bilgisayar bilimleri yüksek lisansı yapıyorum.

Konular

İlgili