Tutorial: Erstellen eines Sprach-zu-Text-Notizenerstellers

Erstellen Sie eine Anwendung, die gesprochenes Audio in organisierte Notizen konvertiert – ganz auf Ihrem Gerät. Die App transkribiert zunächst eine Audiodatei mit einem Sprach-zu-Text-Modell und verwendet dann ein Chatmodell, um die Transkription in saubere Notizen zusammenzufassen und zu organisieren.

In diesem Tutorial erfahren Sie, wie:

  • Einrichten eines Projekts und Installieren des Foundry Local SDK
  • Laden eines Sprach-zu-Text-Modells und Transkribieren einer Audiodatei
  • Laden eines Chatmodells und Zusammenfassen der Transkription
  • Kombinieren Sie die Transkription und die Zusammenfassung zu einer vollständigen App.
  • Bereinigen von Ressourcen

Voraussetzungen

  • Ein Windows, macOS oder Linux-Computer mit mindestens 8 GB RAM.
  • Eine .wav Audiodatei, die transkribiert werden soll (das Lernprogramm verwendet eine Beispieldatei).

Pakete installieren

Beispielrepository

Der vollständige Beispielcode für diesen Artikel ist im Repository Foundry Local GitHub repository verfügbar. So klonen Sie das Repository, und navigieren Sie zur Beispielverwendung:

git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/cs/tutorial-voice-to-text

Wenn Sie Windows entwickeln oder versenden, wählen Sie die Registerkarte Windows aus. Das Windows-Paket ist in die Windows ML Laufzeit integriert. Es bietet den gleichen API-Oberflächenbereich mit einer breiteren Hardwarebeschleunigung.

dotnet add package Microsoft.AI.Foundry.Local.WinML
dotnet add package OpenAI

Die C#-Beispiele im GitHub Repository sind vorkonfigurierte Projekte. Wenn Sie von Grund auf neu erstellen, sollten Sie die Referenz zum Foundry Local SDK lesen, um weitere Details zum Einrichten Ihres C#-Projekts mit Foundry Local zu erhalten.

Transkribieren einer Audiodatei

In diesem Schritt laden Sie ein Sprach-zu-Text-Modell und transkribieren eine Audiodatei. Das Foundry Local SDK verwendet den whisper Modellalias, um die beste Flüstervariante für Ihre Hardware auszuwählen.

  • Öffnen Sie Program.cs und ersetzen Sie dessen Inhalt durch den folgenden Code, um das SDK zu initialisieren, das Sprachmodell zu laden und eine Audiodatei zu transkribieren.

    // Load the speech-to-text model
    var speechModel = await catalog.GetModelAsync("whisper-tiny")
        ?? throw new Exception("Speech model not found");
    
    await speechModel.DownloadAsync(progress =>
    {
        Console.Write($"\rDownloading speech model: {progress:F2}%");
        if (progress >= 100f) Console.WriteLine();
    });
    
    await speechModel.LoadAsync();
    Console.WriteLine("Speech model loaded.");
    
    // Transcribe the audio file
    var audioClient = await speechModel.GetAudioClientAsync();
    var transcriptionText = new StringBuilder();
    
    Console.WriteLine("\nTranscription:");
    var audioResponse = audioClient
        .TranscribeAudioStreamingAsync("meeting-notes.wav", ct);
    await foreach (var chunk in audioResponse)
    {
        Console.Write(chunk.Text);
        transcriptionText.Append(chunk.Text);
    }
    Console.WriteLine();
    
    // Unload the speech model to free memory
    await speechModel.UnloadAsync();
    

    Die GetAudioClientAsync Methode gibt einen Client für Audiovorgänge zurück. Die TranscribeAudioStreamingAsync Methode streamt Transkriptionsblöcke, sobald sie verfügbar sind. Sie sammeln den Text an, damit Sie ihn im nächsten Schritt an das Chatmodell übergeben können.

Hinweis

Ersetzen Sie "meeting-notes.wav" durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Zusammenfassen der Transkription

Verwenden Sie nun ein Chatmodell, um die unformatierte Transkription in strukturierte Notizen zu organisieren. Laden Sie das qwen2.5-0.5b Modell, und senden Sie die Transkription als Kontext mit einer Systemaufforderung, die das Modell anweist, saubere, zusammengefasste Notizen zu erstellen.

Fügen Sie nach dem Transkriptionsschritt den folgenden Code hinzu:

// Load the chat model for summarization
var chatModel = await catalog.GetModelAsync("qwen2.5-0.5b")
    ?? throw new Exception("Chat model not found");

await chatModel.DownloadAsync(progress =>
{
    Console.Write($"\rDownloading chat model: {progress:F2}%");
    if (progress >= 100f) Console.WriteLine();
});

await chatModel.LoadAsync();
Console.WriteLine("Chat model loaded.");

// Summarize the transcription into organized notes
var chatClient = await chatModel.GetChatClientAsync();
var messages = new List<ChatMessage>
{
    new ChatMessage
    {
        Role = "system",
        Content = "You are a note-taking assistant. Summarize " +
                  "the following transcription into organized, " +
                  "concise notes with bullet points."
    },
    new ChatMessage
    {
        Role = "user",
        Content = transcriptionText.ToString()
    }
};

var chatResponse = await chatClient.CompleteChatAsync(messages, ct);
var summary = chatResponse.Choices[0].Message.Content;
Console.WriteLine($"\nSummary:\n{summary}");

// Clean up
await chatModel.UnloadAsync();
Console.WriteLine("\nDone. Models unloaded.");

Die Systemaufforderung gestaltet das Ausgabeformat des Modells. Indem Sie sie anweisen, "organisierte, präzise Notizen mit Aufzählungszeichen" zu erstellen, erhalten Sie strukturierte Inhalte anstelle einer unformatierten Paraphrase.

Kombinieren in einer vollständigen App

Ersetzen Sie den Inhalt Program.cs durch den folgenden vollständigen Code, der eine Audiodatei transkribiert, und fasst die Transkription zusammen:

using Microsoft.AI.Foundry.Local;
using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels;
using Microsoft.Extensions.Logging;
using System.Text;

CancellationToken ct = CancellationToken.None;

var config = new Configuration
{
    AppName = "foundry_local_samples",
    LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information
};

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.SetMinimumLevel(
        Microsoft.Extensions.Logging.LogLevel.Information
    );
});
var logger = loggerFactory.CreateLogger<Program>();

// Initialize the singleton instance
await FoundryLocalManager.CreateAsync(config, logger);
var mgr = FoundryLocalManager.Instance;

// Download and register all execution providers.
var currentEp = "";
await mgr.DownloadAndRegisterEpsAsync((epName, percent) =>
{
    if (epName != currentEp)
    {
        if (currentEp != "") Console.WriteLine();
        currentEp = epName;
    }
    Console.Write($"\r  {epName.PadRight(30)}  {percent,6:F1}%");
});
if (currentEp != "") Console.WriteLine();

var catalog = await mgr.GetCatalogAsync();

// Load the speech-to-text model
var speechModel = await catalog.GetModelAsync("whisper-tiny")
    ?? throw new Exception("Speech model not found");

await speechModel.DownloadAsync(progress =>
{
    Console.Write($"\rDownloading speech model: {progress:F2}%");
    if (progress >= 100f) Console.WriteLine();
});

await speechModel.LoadAsync();
Console.WriteLine("Speech model loaded.");

// Transcribe the audio file
var audioClient = await speechModel.GetAudioClientAsync();
var transcriptionText = new StringBuilder();

Console.WriteLine("\nTranscription:");
var audioResponse = audioClient
    .TranscribeAudioStreamingAsync("meeting-notes.wav", ct);
await foreach (var chunk in audioResponse)
{
    Console.Write(chunk.Text);
    transcriptionText.Append(chunk.Text);
}
Console.WriteLine();

// Unload the speech model to free memory
await speechModel.UnloadAsync();

// Load the chat model for summarization
var chatModel = await catalog.GetModelAsync("qwen2.5-0.5b")
    ?? throw new Exception("Chat model not found");

await chatModel.DownloadAsync(progress =>
{
    Console.Write($"\rDownloading chat model: {progress:F2}%");
    if (progress >= 100f) Console.WriteLine();
});

await chatModel.LoadAsync();
Console.WriteLine("Chat model loaded.");

// Summarize the transcription into organized notes
var chatClient = await chatModel.GetChatClientAsync();
var messages = new List<ChatMessage>
{
    new ChatMessage
    {
        Role = "system",
        Content = "You are a note-taking assistant. Summarize " +
                  "the following transcription into organized, " +
                  "concise notes with bullet points."
    },
    new ChatMessage
    {
        Role = "user",
        Content = transcriptionText.ToString()
    }
};

var chatResponse = await chatClient.CompleteChatAsync(messages, ct);
var summary = chatResponse.Choices[0].Message.Content;
Console.WriteLine($"\nSummary:\n{summary}");

// Clean up
await chatModel.UnloadAsync();
Console.WriteLine("\nDone. Models unloaded.");

Hinweis

Ersetzen Sie "meeting-notes.wav" durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Führen Sie die Notizenanwendung aus:

dotnet run

Es wird eine ähnliche Ausgabe angezeigt wie:

Downloading speech model: 100.00%
Speech model loaded.

Transcription:
OK so let's get started with the weekly sync. First, the backend
API is nearly done. Sarah finished the authentication endpoints
yesterday. We still need to add rate limiting before we go to
staging. On the frontend, the dashboard redesign is about seventy
percent complete. Jake, can you walk us through the new layout?
Great. The charts look good. I think we should add a filter for
date range though. For testing, we have about eighty percent code
coverage on the API. We need to write integration tests for the
new auth flow before Friday. Let's plan to do a full regression
test next Tuesday before the release. Any blockers? OK, sounds
like we are in good shape. Let's wrap up.

Downloading chat model: 100.00%
Chat model loaded.

Summary:
- **Backend API**: Authentication endpoints complete. Rate limiting
  still needed before staging deployment.
- **Frontend**: Dashboard redesign 70% complete. New chart layout
  reviewed. Action item: add a date range filter.
- **Testing**: API code coverage at 80%. Integration tests for the
  auth flow due Friday. Full regression test scheduled for next
  Tuesday before release.
- **Status**: No blockers reported. Team is on track.

Done. Models unloaded.

Die Anwendung transkribiert zunächst den Audioinhalt mit Streamingausgabe und übergibt dann den angesammelten Text an ein Chatmodell, das Schlüsselpunkte extrahiert und in strukturierte Notizen organisiert.

Pakete installieren

Beispielrepository

Der vollständige Beispielcode für diesen Artikel ist im Repository Foundry Local GitHub repository verfügbar. So klonen Sie das Repository, und navigieren Sie zur Beispielverwendung:

git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/js/tutorial-voice-to-text

Wenn Sie Windows entwickeln oder versenden, wählen Sie die Registerkarte Windows aus. Das Windows-Paket ist in die Windows ML Laufzeit integriert. Es bietet den gleichen API-Oberflächenbereich mit einer breiteren Hardwarebeschleunigung.

npm install foundry-local-sdk-winml openai

Transkribieren einer Audiodatei

In diesem Schritt laden Sie ein Sprach-zu-Text-Modell und transkribieren eine Audiodatei. Das Foundry Local SDK verwendet den whisper Modellalias, um die beste Flüstervariante für Ihre Hardware auszuwählen.

  1. Erstellen Sie eine Datei namens app.js.

  2. Fügen Sie den folgenden Code hinzu, um das SDK zu initialisieren, das Sprachmodell zu laden und eine Audiodatei zu transkribieren:

    // Load the speech-to-text model
    const speechModel = await manager.catalog.getModel('whisper-tiny');
    await speechModel.download((progress) => {
        process.stdout.write(
            `\rDownloading speech model: ${progress.toFixed(2)}%`
        );
    });
    console.log('\nSpeech model downloaded.');
    
    await speechModel.load();
    console.log('Speech model loaded.');
    
    // Transcribe the audio file
    const audioClient = speechModel.createAudioClient();
    const transcription = await audioClient.transcribe(
        path.join(__dirname, 'meeting-notes.wav')
    );
    console.log(`\nTranscription:\n${transcription.text}`);
    
    // Unload the speech model to free memory
    await speechModel.unload();
    

    Die createAudioClient Methode gibt einen Client für Audiovorgänge zurück. Die transcribe Methode akzeptiert einen Dateipfad und gibt ein Objekt mit einer text Eigenschaft zurück, die den transkribierten Inhalt enthält.

Hinweis

Ersetzen Sie './meeting-notes.wav' durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Zusammenfassen der Transkription

Verwenden Sie nun ein Chatmodell, um die unformatierte Transkription in strukturierte Notizen zu organisieren. Laden Sie das qwen2.5-0.5b Modell, und senden Sie die Transkription als Kontext mit einer Systemaufforderung, die das Modell anweist, saubere, zusammengefasste Notizen zu erstellen.

Fügen Sie nach dem Transkriptionsschritt den folgenden Code hinzu:

// Load the chat model for summarization
const chatModel = await manager.catalog.getModel('qwen2.5-0.5b');
await chatModel.download((progress) => {
    process.stdout.write(
        `\rDownloading chat model: ${progress.toFixed(2)}%`
    );
});
console.log('\nChat model downloaded.');

await chatModel.load();
console.log('Chat model loaded.');

// Summarize the transcription into organized notes
const chatClient = chatModel.createChatClient();
const messages = [
    {
        role: 'system',
        content: 'You are a note-taking assistant. Summarize ' +
                 'the following transcription into organized, ' +
                 'concise notes with bullet points.'
    },
    {
        role: 'user',
        content: transcription.text
    }
];

const response = await chatClient.completeChat(messages);
const summary = response.choices[0]?.message?.content;
console.log(`\nSummary:\n${summary}`);

// Clean up
await chatModel.unload();
console.log('\nDone. Models unloaded.');

Die Systemaufforderung gestaltet das Ausgabeformat des Modells. Indem Sie sie anweisen, "organisierte, präzise Notizen mit Aufzählungszeichen" zu erstellen, erhalten Sie strukturierte Inhalte anstelle einer unformatierten Paraphrase.

Kombinieren in einer vollständigen App

Erstellen Sie eine Datei mit dem Namen app.js , und fügen Sie den folgenden vollständigen Code hinzu, der eine Audiodatei transkribiert, und fasst die Transkription zusammen:

import { FoundryLocalManager } from 'foundry-local-sdk';
import { fileURLToPath } from 'url';
import path from 'path';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

// Initialize the Foundry Local SDK
const manager = FoundryLocalManager.create({
    appName: 'foundry_local_samples',
    logLevel: 'info'
});

// Download and register all execution providers.
let currentEp = '';
await manager.downloadAndRegisterEps((epName, percent) => {
    if (epName !== currentEp) {
        if (currentEp !== '') process.stdout.write('\n');
        currentEp = epName;
    }
    process.stdout.write(`\r  ${epName.padEnd(30)}  ${percent.toFixed(1).padStart(5)}%`);
});
if (currentEp !== '') process.stdout.write('\n');

// Load the speech-to-text model
const speechModel = await manager.catalog.getModel('whisper-tiny');
await speechModel.download((progress) => {
    process.stdout.write(
        `\rDownloading speech model: ${progress.toFixed(2)}%`
    );
});
console.log('\nSpeech model downloaded.');

await speechModel.load();
console.log('Speech model loaded.');

// Transcribe the audio file
const audioClient = speechModel.createAudioClient();
const transcription = await audioClient.transcribe(
    path.join(__dirname, 'meeting-notes.wav')
);
console.log(`\nTranscription:\n${transcription.text}`);

// Unload the speech model to free memory
await speechModel.unload();

// Load the chat model for summarization
const chatModel = await manager.catalog.getModel('qwen2.5-0.5b');
await chatModel.download((progress) => {
    process.stdout.write(
        `\rDownloading chat model: ${progress.toFixed(2)}%`
    );
});
console.log('\nChat model downloaded.');

await chatModel.load();
console.log('Chat model loaded.');

// Summarize the transcription into organized notes
const chatClient = chatModel.createChatClient();
const messages = [
    {
        role: 'system',
        content: 'You are a note-taking assistant. Summarize ' +
                 'the following transcription into organized, ' +
                 'concise notes with bullet points.'
    },
    {
        role: 'user',
        content: transcription.text
    }
];

const response = await chatClient.completeChat(messages);
const summary = response.choices[0]?.message?.content;
console.log(`\nSummary:\n${summary}`);

// Clean up
await chatModel.unload();
console.log('\nDone. Models unloaded.');

Hinweis

Ersetzen Sie './meeting-notes.wav' durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Führen Sie die Notizenanwendung aus:

node app.js

Es wird eine ähnliche Ausgabe angezeigt wie:

Downloading speech model: 100.00%
Speech model downloaded.
Speech model loaded.

Transcription:
OK so let's get started with the weekly sync. First, the backend
API is nearly done. Sarah finished the authentication endpoints
yesterday. We still need to add rate limiting before we go to
staging. On the frontend, the dashboard redesign is about seventy
percent complete. Jake, can you walk us through the new layout?
Great. The charts look good. I think we should add a filter for
date range though. For testing, we have about eighty percent code
coverage on the API. We need to write integration tests for the
new auth flow before Friday. Let's plan to do a full regression
test next Tuesday before the release. Any blockers? OK, sounds
like we are in good shape. Let's wrap up.

Downloading chat model: 100.00%
Chat model downloaded.
Chat model loaded.

Summary:
- **Backend API**: Authentication endpoints complete. Rate limiting
  still needed before staging deployment.
- **Frontend**: Dashboard redesign 70% complete. New chart layout
  reviewed. Action item: add a date range filter.
- **Testing**: API code coverage at 80%. Integration tests for the
  auth flow due Friday. Full regression test scheduled for next
  Tuesday before release.
- **Status**: No blockers reported. Team is on track.

Done. Models unloaded.

Die Anwendung transkribiert zuerst den Audioinhalt und übergibt diesen Text dann an ein Chatmodell, das Schlüsselpunkte extrahiert und in strukturierte Notizen organisiert.

Pakete installieren

Beispielrepository

Der vollständige Beispielcode für diesen Artikel ist im Repository Foundry Local GitHub repository verfügbar. So klonen Sie das Repository, und navigieren Sie zur Beispielverwendung:

git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/python/tutorial-voice-to-text

Wenn Sie Windows entwickeln oder versenden, wählen Sie die Registerkarte Windows aus. Das Windows-Paket ist in die Windows ML Laufzeit integriert. Es bietet den gleichen API-Oberflächenbereich mit einer breiteren Hardwarebeschleunigung.

pip install foundry-local-sdk-winml openai

Transkribieren einer Audiodatei

In diesem Schritt laden Sie ein Sprach-zu-Text-Modell und transkribieren eine Audiodatei. Das Foundry Local SDK verwendet den whisper Modellalias, um die beste Flüstervariante für Ihre Hardware auszuwählen.

  1. Erstellen Sie eine Datei namens app.py.

  2. Fügen Sie den folgenden Code hinzu, um das SDK zu initialisieren, das Sprachmodell zu laden und eine Audiodatei zu transkribieren:

    # Load the speech-to-text model
    speech_model = manager.catalog.get_model("whisper-tiny")
    speech_model.download(
        lambda progress: print(
            f"\rDownloading speech model: {progress:.2f}%",
            end="",
            flush=True,
        )
    )
    print()
    speech_model.load()
    print("Speech model loaded.")
    
    # Transcribe the audio file
    audio_client = speech_model.get_audio_client()
    transcription = audio_client.transcribe("meeting-notes.wav")
    print(f"\nTranscription:\n{transcription.text}")
    
    # Unload the speech model to free memory
    speech_model.unload()
    

    Die get_audio_client Methode gibt einen Client für Audiovorgänge zurück. Die transcribe Methode akzeptiert einen Dateipfad und gibt ein Objekt mit einer text Eigenschaft zurück, die den transkribierten Inhalt enthält.

Hinweis

Ersetzen Sie "meeting-notes.wav" durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Zusammenfassen der Transkription

Verwenden Sie nun ein Chatmodell, um die unformatierte Transkription in strukturierte Notizen zu organisieren. Laden Sie das qwen2.5-0.5b Modell, und senden Sie die Transkription als Kontext mit einer Systemaufforderung, die das Modell anweist, saubere, zusammengefasste Notizen zu erstellen.

Fügen Sie nach dem Transkriptionsschritt den folgenden Code hinzu:

# Load the chat model for summarization
chat_model = manager.catalog.get_model("qwen2.5-0.5b")
chat_model.download(
    lambda progress: print(
        f"\rDownloading chat model: {progress:.2f}%",
        end="",
        flush=True,
    )
)
print()
chat_model.load()
print("Chat model loaded.")

# Summarize the transcription into organized notes
client = chat_model.get_chat_client()
messages = [
    {
        "role": "system",
        "content": "You are a note-taking assistant. "
                   "Summarize the following transcription "
                   "into organized, concise notes with "
                   "bullet points.",
    },
    {"role": "user", "content": transcription.text},
]

response = client.complete_chat(messages)
summary = response.choices[0].message.content
print(f"\nSummary:\n{summary}")

# Clean up
chat_model.unload()
print("\nDone. Models unloaded.")

Die Systemaufforderung gestaltet das Ausgabeformat des Modells. Indem Sie sie anweisen, "organisierte, präzise Notizen mit Aufzählungszeichen" zu erstellen, erhalten Sie strukturierte Inhalte anstelle einer unformatierten Paraphrase.

Kombinieren in einer vollständigen App

Erstellen Sie eine Datei mit dem Namen app.py , und fügen Sie den folgenden vollständigen Code hinzu, der eine Audiodatei transkribiert, und fasst die Transkription zusammen:

from foundry_local_sdk import Configuration, FoundryLocalManager


def main():
    # Initialize the Foundry Local SDK
    config = Configuration(app_name="foundry_local_samples")
    FoundryLocalManager.initialize(config)
    manager = FoundryLocalManager.instance

    # Download and register all execution providers.
    current_ep = ""
    def ep_progress(ep_name: str, percent: float):
        nonlocal current_ep
        if ep_name != current_ep:
            if current_ep:
                print()
            current_ep = ep_name
        print(f"\r  {ep_name:<30}  {percent:5.1f}%", end="", flush=True)

    manager.download_and_register_eps(progress_callback=ep_progress)
    if current_ep:
        print()

    # Load the speech-to-text model
    speech_model = manager.catalog.get_model("whisper-tiny")
    speech_model.download(
        lambda progress: print(
            f"\rDownloading speech model: {progress:.2f}%",
            end="",
            flush=True,
        )
    )
    print()
    speech_model.load()
    print("Speech model loaded.")

    # Transcribe the audio file
    audio_client = speech_model.get_audio_client()
    transcription = audio_client.transcribe("meeting-notes.wav")
    print(f"\nTranscription:\n{transcription.text}")

    # Unload the speech model to free memory
    speech_model.unload()

    # Load the chat model for summarization
    chat_model = manager.catalog.get_model("qwen2.5-0.5b")
    chat_model.download(
        lambda progress: print(
            f"\rDownloading chat model: {progress:.2f}%",
            end="",
            flush=True,
        )
    )
    print()
    chat_model.load()
    print("Chat model loaded.")

    # Summarize the transcription into organized notes
    client = chat_model.get_chat_client()
    messages = [
        {
            "role": "system",
            "content": "You are a note-taking assistant. "
                       "Summarize the following transcription "
                       "into organized, concise notes with "
                       "bullet points.",
        },
        {"role": "user", "content": transcription.text},
    ]

    response = client.complete_chat(messages)
    summary = response.choices[0].message.content
    print(f"\nSummary:\n{summary}")

    # Clean up
    chat_model.unload()
    print("\nDone. Models unloaded.")


if __name__ == "__main__":
    main()

Hinweis

Ersetzen Sie "meeting-notes.wav" durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Führen Sie die Notizenanwendung aus:

python app.py

Es wird eine ähnliche Ausgabe angezeigt wie:

Downloading speech model: 100.00%
Speech model loaded.

Transcription:
OK so let's get started with the weekly sync. First, the backend
API is nearly done. Sarah finished the authentication endpoints
yesterday. We still need to add rate limiting before we go to
staging. On the frontend, the dashboard redesign is about seventy
percent complete. Jake, can you walk us through the new layout?
Great. The charts look good. I think we should add a filter for
date range though. For testing, we have about eighty percent code
coverage on the API. We need to write integration tests for the
new auth flow before Friday. Let's plan to do a full regression
test next Tuesday before the release. Any blockers? OK, sounds
like we are in good shape. Let's wrap up.

Downloading chat model: 100.00%
Chat model loaded.

Summary:
- **Backend API**: Authentication endpoints complete. Rate limiting
  still needed before staging deployment.
- **Frontend**: Dashboard redesign 70% complete. New chart layout
  reviewed. Action item: add a date range filter.
- **Testing**: API code coverage at 80%. Integration tests for the
  auth flow due Friday. Full regression test scheduled for next
  Tuesday before release.
- **Status**: No blockers reported. Team is on track.

Done. Models unloaded.

Die Anwendung transkribiert zuerst den Audioinhalt und übergibt diesen Text dann an ein Chatmodell, das Schlüsselpunkte extrahiert und in strukturierte Notizen organisiert.

Pakete installieren

Beispielrepository

Der vollständige Beispielcode für diesen Artikel ist im Repository Foundry Local GitHub repository verfügbar. So klonen Sie das Repository, und navigieren Sie zur Beispielverwendung:

git clone https://github.com/microsoft/Foundry-Local.git
cd Foundry-Local/samples/rust/tutorial-voice-to-text

Wenn Sie Windows entwickeln oder versenden, wählen Sie die Registerkarte Windows aus. Das Windows-Paket ist in die Windows ML Laufzeit integriert. Es bietet den gleichen API-Oberflächenbereich mit einer breiteren Hardwarebeschleunigung.

cargo add foundry-local-sdk --features winml
cargo add tokio --features full
cargo add tokio-stream anyhow

Transkribieren einer Audiodatei

In diesem Schritt laden Sie ein Sprach-zu-Text-Modell und transkribieren eine Audiodatei. Das Foundry Local SDK verwendet den whisper Modellalias, um die beste Flüstervariante für Ihre Hardware auszuwählen.

  • Öffnen Sie src/main.rs und ersetzen Sie dessen Inhalt durch den folgenden Code, um das SDK zu initialisieren, das Sprachmodell zu laden und eine Audiodatei zu transkribieren.

    // Load the speech-to-text model
    let speech_model = manager
        .catalog()
        .get_model("whisper-tiny")
        .await?;
    
    if !speech_model.is_cached().await? {
        println!("Downloading speech model...");
        speech_model
            .download(Some(|progress: f64| {
                print!("\r  {progress:.1}%");
                io::stdout().flush().ok();
            }))
            .await?;
        println!();
    }
    
    speech_model.load().await?;
    println!("Speech model loaded.");
    
    // Transcribe the audio file
    let audio_client = speech_model.create_audio_client();
    let transcription = audio_client
        .transcribe("meeting-notes.wav")
        .await?;
    println!("\nTranscription:\n{}", transcription.text);
    
    // Unload the speech model to free memory
    speech_model.unload().await?;
    

    Die create_audio_client Methode gibt einen Client für Audiovorgänge zurück. Die transcribe Methode akzeptiert einen Dateipfad und gibt ein Objekt mit einem text Feld zurück, das den transkribierten Inhalt enthält.

Hinweis

Ersetzen Sie "meeting-notes.wav" durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Zusammenfassen der Transkription

Verwenden Sie nun ein Chatmodell, um die unformatierte Transkription in strukturierte Notizen zu organisieren. Laden Sie das qwen2.5-0.5b Modell, und senden Sie die Transkription als Kontext mit einer Systemaufforderung, die das Modell anweist, saubere, zusammengefasste Notizen zu erstellen.

Fügen Sie den folgenden Code nach dem Transkriptionsschritt innerhalb der main Funktion hinzu:

// Load the chat model for summarization
let chat_model = manager
    .catalog()
    .get_model("qwen2.5-0.5b")
    .await?;

if !chat_model.is_cached().await? {
    println!("Downloading chat model...");
    chat_model
        .download(Some(|progress: f64| {
            print!("\r  {progress:.1}%");
            io::stdout().flush().ok();
        }))
        .await?;
    println!();
}

chat_model.load().await?;
println!("Chat model loaded.");

// Summarize the transcription into organized notes
let client = chat_model
    .create_chat_client()
    .temperature(0.7)
    .max_tokens(512);

let messages: Vec<ChatCompletionRequestMessage> = vec![
    ChatCompletionRequestSystemMessage::from(
        "You are a note-taking assistant. Summarize \
         the following transcription into organized, \
         concise notes with bullet points.",
    )
    .into(),
    ChatCompletionRequestUserMessage::from(
        transcription.text.as_str(),
    )
    .into(),
];

let response = client
    .complete_chat(&messages, None)
    .await?;
let summary = response.choices[0]
    .message
    .content
    .as_deref()
    .unwrap_or("");
println!("\nSummary:\n{}", summary);

// Clean up
chat_model.unload().await?;
println!("\nDone. Models unloaded.");

Die Systemaufforderung gestaltet das Ausgabeformat des Modells. Indem Sie sie anweisen, "organisierte, präzise Notizen mit Aufzählungszeichen" zu erstellen, erhalten Sie strukturierte Inhalte anstelle einer unformatierten Paraphrase.

Kombinieren in einer vollständigen App

Ersetzen Sie den Inhalt src/main.rs durch den folgenden vollständigen Code, der eine Audiodatei transkribiert, und fasst die Transkription zusammen:

use foundry_local_sdk::{
    ChatCompletionRequestMessage,
    ChatCompletionRequestSystemMessage,
    ChatCompletionRequestUserMessage,
    FoundryLocalConfig, FoundryLocalManager,
};
use std::io::{self, Write};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize the Foundry Local SDK
    let manager = FoundryLocalManager::create(
        FoundryLocalConfig::new("note-taker"),
    )?;

    // Download and register all execution providers.
    manager
        .download_and_register_eps_with_progress(None, {
            let mut current_ep = String::new();
            move |ep_name: &str, percent: f64| {
                if ep_name != current_ep {
                    if !current_ep.is_empty() {
                        println!();
                    }
                    current_ep = ep_name.to_string();
                }
                print!("\r  {:<30}  {:5.1}%", ep_name, percent);
                io::stdout().flush().ok();
            }
        })
        .await?;
    println!();

    // Load the speech-to-text model
    let speech_model = manager
        .catalog()
        .get_model("whisper-tiny")
        .await?;

    if !speech_model.is_cached().await? {
        println!("Downloading speech model...");
        speech_model
            .download(Some(|progress: f64| {
                print!("\r  {progress:.1}%");
                io::stdout().flush().ok();
            }))
            .await?;
        println!();
    }

    speech_model.load().await?;
    println!("Speech model loaded.");

    // Transcribe the audio file
    let audio_client = speech_model.create_audio_client();
    let transcription = audio_client
        .transcribe("meeting-notes.wav")
        .await?;
    println!("\nTranscription:\n{}", transcription.text);

    // Unload the speech model to free memory
    speech_model.unload().await?;

    // Load the chat model for summarization
    let chat_model = manager
        .catalog()
        .get_model("qwen2.5-0.5b")
        .await?;

    if !chat_model.is_cached().await? {
        println!("Downloading chat model...");
        chat_model
            .download(Some(|progress: f64| {
                print!("\r  {progress:.1}%");
                io::stdout().flush().ok();
            }))
            .await?;
        println!();
    }

    chat_model.load().await?;
    println!("Chat model loaded.");

    // Summarize the transcription into organized notes
    let client = chat_model
        .create_chat_client()
        .temperature(0.7)
        .max_tokens(512);

    let messages: Vec<ChatCompletionRequestMessage> = vec![
        ChatCompletionRequestSystemMessage::from(
            "You are a note-taking assistant. Summarize \
             the following transcription into organized, \
             concise notes with bullet points.",
        )
        .into(),
        ChatCompletionRequestUserMessage::from(
            transcription.text.as_str(),
        )
        .into(),
    ];

    let response = client
        .complete_chat(&messages, None)
        .await?;
    let summary = response.choices[0]
        .message
        .content
        .as_deref()
        .unwrap_or("");
    println!("\nSummary:\n{}", summary);

    // Clean up
    chat_model.unload().await?;
    println!("\nDone. Models unloaded.");

    Ok(())
}

Hinweis

Ersetzen Sie "meeting-notes.wav" durch den Pfad zu Ihrer Audiodatei. Unterstützte Formate sind WAV, MP3 und FLAC.

Führen Sie die Notizenanwendung aus:

cargo run

Es wird eine ähnliche Ausgabe angezeigt wie:

Downloading speech model: 100.00%
Speech model loaded.

Transcription:
OK so let's get started with the weekly sync. First, the backend
API is nearly done. Sarah finished the authentication endpoints
yesterday. We still need to add rate limiting before we go to
staging. On the frontend, the dashboard redesign is about seventy
percent complete. Jake, can you walk us through the new layout?
Great. The charts look good. I think we should add a filter for
date range though. For testing, we have about eighty percent code
coverage on the API. We need to write integration tests for the
new auth flow before Friday. Let's plan to do a full regression
test next Tuesday before the release. Any blockers? OK, sounds
like we are in good shape. Let's wrap up.

Downloading chat model: 100.00%
Chat model loaded.

Summary:
- **Backend API**: Authentication endpoints complete. Rate limiting
  still needed before staging deployment.
- **Frontend**: Dashboard redesign 70% complete. New chart layout
  reviewed. Action item: add a date range filter.
- **Testing**: API code coverage at 80%. Integration tests for the
  auth flow due Friday. Full regression test scheduled for next
  Tuesday before release.
- **Status**: No blockers reported. Team is on track.

Done. Models unloaded.

Die Anwendung transkribiert zuerst den Audioinhalt und übergibt diesen Text dann an ein Chatmodell, das Schlüsselpunkte extrahiert und in strukturierte Notizen organisiert.

Bereinigen von Ressourcen

Die Gewichtungen des Modells verbleiben im lokalen Cache, nachdem Sie ein Modell entladen haben. Dies bedeutet, dass beim nächsten Ausführen der Anwendung der Downloadschritt übersprungen wird und das Modell schneller geladen wird. Es ist keine zusätzliche Bereinigung erforderlich, es sei denn, Sie möchten Speicherplatz freigeben.