Перейти к содержанию
Публикация AiManual

Распознавание речи в Unity: практическое руководство по интеграции AI-моделей через Hugging Face API

Пошаговый гайд по интеграции распознавания речи в Unity через Hugging Face API: запись с микрофона, конвертация в WAV, отправка запроса к Whisper, обработка оши

Коротко

Что будет в материале

  1. 01

    Введение: зачем Unity-разработчику распознавание речи в 2025 году

  2. 02

    Обзор возможностей: какие AI-модели распознавания речи доступны через Hugging Face

  3. 03

    Подготовка Unity-проекта: настройка сцены и UI для голосового ввода

  4. 04

    Запись аудио с микрофона в Unity: работа с Microphone API

Распознавание речи в Unity через Hugging Face API решается за четыре шага: настройка UI, запись аудио с микрофона, конвертация в WAV и отправка запроса к модели Whisper или Wav2Vec2. Голосовое управление в играх перестало быть экспериментальной фичей. В 2025 году разработчики встраивают голосовые команды в геймплей, диалоги с NPC и субтитры для слабослышащих игроков. Hugging Face API даёт доступ к готовым моделям без обучения собственных нейросетей и без развёртывания серверной инфраструктуры.

Этот гайд построен на реальном опыте интеграции: от создания кнопки записи до обработки ошибок 429 и смены эндпоинтов API. Вы получите рабочий код на C#, который можно вставить в проект Unity 2022 LTS или Unity 6. Отдельно разберём актуальные проблемы 2025-2026 годов и альтернативы, если Hugging Face не подходит под ваши ограничения.

Если вы только начинаете работать с Hugging Face в Unity, сначала посмотрите базовое руководство по интеграции Hugging Face API в Unity. Там разобраны установка пакета, настройка API-ключа и выполнение простых задач вроде Sentence Similarity.

Введение: зачем Unity-разработчику распознавание речи в 2025 году

Голосовые интерфейсы вышли за пределы умных колонок. Игроки ожидают, что персонаж отреагирует на фразу «открой дверь» или «покажи инвентарь». По данным аналитики мобильных приложений, голосовой ввод сокращает время выполнения частых действий на 30-40% по сравнению с многоуровневыми меню. Для разработчиков это прямой аргумент: голосовое управление снижает трение в UX.

В Unity-проектах распознавание речи решает три задачи. Первая: голосовые команды для управления игрой, от перемещения до вызова способностей. Вторая: диалоги с NPC, когда игрок говорит фразу, а система передаёт её языковой модели для генерации ответа. Третья: доступность, субтитры в реальном времени для слабослышащих игроков и голосовой ввод для людей с ограниченной моторикой.

Hugging Face API упрощает запуск: вы отправляете аудиофайл, получаете текст. Не нужно обучать модель, настраивать CUDA или арендовать GPU-сервер. Для прототипа достаточно бесплатного тарифа, для продакшена есть платные опции с меньшей задержкой.

Обзор возможностей: какие AI-модели распознавания речи доступны через Hugging Face

Выбор модели определяет точность, скорость и стоимость запроса. На Hugging Face размещены сотни моделей ASR, но для Unity-проектов практическую ценность имеют три архитектуры: Whisper, Wav2Vec2 и HuBERT.

Whisper: универсальное решение от OpenAI

Whisper распознаёт 99 языков, устойчив к фоновому шуму и акцентам. Модель обучена на 680 000 часах аудио, из которых 117 000 часов покрывают неанглийские языки. Для Unity-разработчика это означает: одна модель работает для русской, английской и мультиязычной аудитории без дообучения.

Недостатки: размер и скорость. Базовая версия Whisper small занимает около 1 ГБ, large - 3 ГБ. Запрос через API занимает от 1 до 5 секунд в зависимости от длины аудио и загруженности сервера. Для пошаговых игр это приемлемо, для экшена с мгновенной реакцией - нет.

Wav2Vec2 и HuBERT: легковесные альтернативы

Wav2Vec2 и HuBERT работают быстрее Whisper и требуют меньше вычислительных ресурсов. Wav2Vec2 base содержит 95 миллионов параметров, что в 16 раз меньше Whisper large. Это критично для мобильных платформ и WebGL.

Ограничение: модели Wav2Vec2 и HuBERT обычно дообучены под конкретный язык. Для русского языка нужно искать fine-tuned версию, например, wav2vec2-large-ru. Если ваша аудитория говорит на нескольких языках, Whisper будет практичнее.

Правило выбора: для прототипа и мультиязычности берите Whisper. Для мобильных проектов с одним языком и жёстким бюджетом по задержке - Wav2Vec2. HuBERT рассматривайте, если нужна максимальная скорость и вы готовы дообучать модель под свой домен.

Подготовка Unity-проекта: настройка сцены и UI для голосового ввода

Начните с минимального интерфейса. Вам нужны три элемента: кнопка записи, текстовое поле для результата и индикатор состояния. Создайте Canvas, добавьте Button с подписью «Записать», Text для вывода распознанного текста и второй Text для статуса: «Готов», «Запись...», «Отправка...», «Ошибка».

Создание минимального UI: кнопка, текстовое поле, статус

В Unity Editor создайте Canvas через GameObject → UI → Canvas. Добавьте Button через GameObject → UI → Button. Добавьте два Text через GameObject → UI → Text. Расположите элементы: кнопка внизу экрана, текстовое поле результата в центре, статус над кнопкой.

Назначьте обработчик на кнопку: в компоненте Button найдите секцию OnClick, нажмите «+», перетащите объект со скриптом и выберите метод, который будет запускать запись. Создайте C# скрипт SpeechRecognizer и прикрепите его к объекту в сцене. В скрипте объявите ссылки на UI-элементы через SerializeField.

using UnityEngine;
using UnityEngine.UI;

public class SpeechRecognizer : MonoBehaviour
{
    [SerializeField] private Button recordButton;
    [SerializeField] private Text resultText;
    [SerializeField] private Text statusText;

    private void Start()
    {
        recordButton.onClick.AddListener(StartRecording);
        statusText.text = "Готов";
    }

    private void StartRecording()
    {
        statusText.text = "Запись...";
    }
}

Запись аудио с микрофона в Unity: работа с Microphone API

Unity предоставляет класс Microphone для захвата аудио. Метод Microphone.Start возвращает AudioClip с записью. Метод Microphone.End останавливает запись. Метод Microphone.GetData заполняет массив float сэмплами.

Обработка разрешений и ошибок доступа к микрофону

Перед записью проверьте наличие устройств через Microphone.devices. Если массив пуст, микрофон не подключён. На Android и iOS пользователь должен дать разрешение на доступ к микрофону. Unity запрашивает его автоматически при первом вызове Microphone.Start, но лучше обработать отказ.

На Android в манифесте должна быть запись android.permission.RECORD_AUDIO. Unity добавляет её автоматически, если в Player Settings включён Microphone в разделе Internet Access. На iOS в Info.plist добавьте NSMicrophoneUsageDescription с описанием, зачем нужен микрофон.

private AudioClip recordedClip;
private const int MaxRecordingSeconds = 10;

private void StartRecording()
{
    if (Microphone.devices.Length == 0)
    {
        statusText.text = "Микрофон не найден";
        return;
    }

    recordedClip = Microphone.Start(null, false, MaxRecordingSeconds, 16000);
    statusText.text = "Запись...";
}

private void StopRecording()
{
    Microphone.End(null);
    statusText.text = "Отправка...";
}

Частота дискретизации 16000 Гц достаточна для распознавания речи и уменьшает размер файла. Whisper работает с 16000 Гц, поэтому конвертация не потребует ресемплинга.

Конвертация аудио в WAV: подготовка данных для API

Hugging Face API принимает аудио в формате WAV с PCM-кодированием. Unity хранит аудио в AudioClip как массив float от -1 до 1. Нужно преобразовать эти данные в байты PCM 16-bit и добавить WAV-заголовок.

Написание конвертера AudioClip в WAV

Функция конвертации берёт AudioClip, извлекает сэмплы через GetData, преобразует float в short и записывает байты в массив. WAV-заголовок содержит информацию о частоте дискретизации, количестве каналов и битности.

private byte[] ConvertAudioClipToWav(AudioClip clip)
{
    float[] samples = new float[clip.samples * clip.channels];
    clip.GetData(samples, 0);

    byte[] wavData = new byte[samples.Length * 2 + 44];
    int sampleRate = clip.frequency;
    int channels = clip.channels;

    // WAV header
    System.Buffer.BlockCopy(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, wavData, 0, 4);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes(wavData.Length - 8), 0, wavData, 4, 4);
    System.Buffer.BlockCopy(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, wavData, 8, 4);
    System.Buffer.BlockCopy(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, wavData, 12, 4);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes(16), 0, wavData, 16, 4);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes((short)1), 0, wavData, 20, 2);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes((short)channels), 0, wavData, 22, 2);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes(sampleRate), 0, wavData, 24, 4);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes(sampleRate * channels * 2), 0, wavData, 28, 4);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes((short)(channels * 2)), 0, wavData, 32, 2);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes((short)16), 0, wavData, 34, 2);
    System.Buffer.BlockCopy(System.Text.Encoding.UTF8.GetBytes("data"), 0, wavData, 36, 4);
    System.Buffer.BlockCopy(System.BitConverter.GetBytes(samples.Length * 2), 0, wavData, 40, 4);

    int offset = 44;
    for (int i = 0; i < samples.Length; i++)
    {
        short pcmValue = (short)Mathf.Clamp(samples[i] * 32767f, -32768f, 32767f);
        byte[] bytes = System.BitConverter.GetBytes(pcmValue);
        System.Buffer.BlockCopy(bytes, 0, wavData, offset, 2);
        offset += 2;
    }

    return wavData;
}

Функция создаёт моно или стерео WAV в зависимости от каналов AudioClip. Для распознавания речи моно достаточно, поэтому записывайте с одним каналом, если API не требует иного.

Отправка запроса к Hugging Face API: интеграция через UnityWebRequest

Для отправки аудио используйте UnityWebRequest. Запрос идёт на эндпоинт модели, например, https://api-inference.huggingface.co/models/openai/whisper-small. Тело запроса - байты WAV-файла. Метод - POST.

Аутентификация и заголовки запроса

API-ключ Hugging Face передаётся в заголовке Authorization с префиксом Bearer. Получите ключ на странице Settings → Access Tokens на сайте Hugging Face. Не храните ключ в открытом виде в коде для продакшена, используйте переменные окружения или серверный прокси.

private const string ApiKey = "hf_ваш_ключ";
private const string ApiUrl = "https://api-inference.huggingface.co/models/openai/whisper-small";

private IEnumerator SendAudioToApi(byte[] wavData)
{
    using (UnityWebRequest request = new UnityWebRequest(ApiUrl, "POST"))
    {
        request.uploadHandler = new UploadHandlerRaw(wavData);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Authorization", "Bearer " + ApiKey);
        request.SetRequestHeader("Content-Type", "audio/wav");

        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
        {
            ProcessResponse(request.downloadHandler.text);
        }
        else
        {
            HandleError(request.responseCode, request.error);
        }
    }
}

Обработка ответа и извлечение текста

Ответ Hugging Face API для ASR-моделей - JSON с полем text. Для Whisper ответ выглядит так: {"text": "распознанная фраза"}. Используйте JsonUtility для парсинга.

[System.Serializable]
private class AsrResponse
{
    public string text;
}

private void ProcessResponse(string json)
{
    AsrResponse response = JsonUtility.FromJson(json);
    resultText.text = response.text;
    statusText.text = "Готов";
}

Если модель возвращает массив объектов, например, для некоторых Wav2Vec2 моделей, создайте обёртку с List и парсите соответствующим образом.

Обработка ошибок и тайм-аутов: опыт реальной интеграции в 2025-2026

Ошибки при работе с Hugging Face API делятся на три группы: аутентификация, лимиты и доступность сервера. Код 401 означает неверный или просроченный API-ключ. Код 429 - превышение лимита запросов. Код 503 - модель загружается или сервер перегружен.

Актуальные проблемы с эндпоинтами Hugging Face API

В 2025-2026 годах Hugging Face обновлял структуру эндпоинтов. Часть старых URL перестала работать без предупреждения. Проверяйте актуальный URL на странице модели во вкладке «Deploy → Inference API». Если запрос возвращает 404, сверьте эндпоинт с документацией модели.

Ещё одна проблема: холодный старт модели. Если модель не использовалась некоторое время, первый запрос может занять 10-30 секунд, потому что сервер загружает её в память. Для продакшена используйте Inference Endpoints с постоянным развёртыванием, это убирает холодный старт.

Стратегии повторных попыток и graceful degradation

Реализуйте повторные попытки с экспоненциальной задержкой. При ошибке 429 или 503 подождите 1 секунду, потом 2, потом 4, максимум 3 попытки. Если все попытки неудачны, покажите пользователю fallback-сообщение: «Не удалось распознать речь, попробуйте ещё раз».

private IEnumerator SendWithRetry(byte[] wavData, int maxRetries = 3)
{
    int retryDelay = 1;
    for (int attempt = 0; attempt < maxRetries; attempt++)
    {
        using (UnityWebRequest request = CreateRequest(wavData))
        {
            request.timeout = 30;
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.Success)
            {
                ProcessResponse(request.downloadHandler.text);
                yield break;
            }

            if (request.responseCode == 429 || request.responseCode == 503)
            {
                yield return new WaitForSeconds(retryDelay);
                retryDelay *= 2;
            }
            else
            {
                HandleError(request.responseCode, request.error);
                yield break;
            }
        }
    }
    statusText.text = "Сервис недоступен, попробуйте позже";
}

Тайм-аут запроса установите на 30 секунд. Whisper small обрабатывает 10 секунд аудио за 2-5 секунд, но при холодном старте или высокой нагрузке время растёт. Слишком короткий тайм-аут приведёт к ложным ошибкам.

Практические сценарии: голосовое управление, диалоги с NPC, доступность

Распознанный текст открывает три практических сценария в играх. Каждый требует разной архитектуры обработки.

Голосовые команды для управления игрой

Сопоставляйте распознанный текст с набором команд через нормализацию: приведите строку к нижнему регистру, удалите знаки препинания, проверьте вхождение ключевых слов. Команда «открой инвентарь» сработает и на «открой инвентарь пожалуйста».

private void ProcessVoiceCommand(string text)
{
    string normalized = text.ToLower().Trim();
    
    if (normalized.Contains("инвентарь"))
    {
        OpenInventory();
    }
    else if (normalized.Contains("карта"))
    {
        OpenMap();
    }
    else if (normalized.Contains("сохранить"))
    {
        SaveGame();
    }
}

Диалоги с NPC: интеграция с языковыми моделями

Распознанный текст передаётся в LLM для генерации ответа NPC. Связка Whisper для ASR и языковой модели для генерации создаёт полноценный голосовой диалог. Ответ NPC можно озвучить через TTS-модель, например, SpeechT5. Подробнее об этой модели читайте в разборе SpeechT5: универсальная модель для синтеза, распознавания и конвертации речи.

Для диалоговой системы держите контекст разговора в списке сообщений и отправляйте его вместе с новой фразой игрока. Это позволяет NPC помнить, о чём шла речь ранее.

Оптимизация UX: снижение задержки и улучшение отзывчивости

Задержка между окончанием речи и появлением текста - главный фактор восприятия качества. Игрок ждёт 2-5 секунд при использовании Whisper через Hugging Face API. Сократить задержку можно тремя способами.

Потоковое распознавание: уменьшение времени ожидания

Потоковая передача отправляет аудио чанками по мере записи, а не одним файлом после остановки. Это снижает воспринимаемую задержку: первые слова распознаются, пока игрок продолжает говорить. Hugging Face Inference API поддерживает потоковую передачу через WebSocket для некоторых моделей, но реализация в Unity сложнее, чем простой POST-запрос.

Для Unity проще использовать промежуточный сервер, который принимает аудиопоток и обращается к Hugging Face. Сервер держит WebSocket-соединение с Unity-клиентом и отправляет распознанные фрагменты по мере готовности.

Дополнительно кэшируйте результаты частых команд. Если игрок говорит «открой карту» десять раз, не отправляйте каждый запрос к API - проверьте локальный кэш распознанных фраз.

Альтернативы Hugging Face: сравнение с Claude, OpenAI и локальными моделями

Hugging Face API - практичный старт, но не единственный вариант. Выбор зависит от требований к задержке, стоимости и офлайн-доступности.

Claude и OpenAI: встроенные голосовые возможности

Claude поддерживает голосовой ввод в мобильных приложениях для iOS и Android. Функция диктовки включена по умолчанию для всех пользователей: бесплатных, Pro, Max, командных и корпоративных. В Claude Code голосовой ввод работает только при авторизации через аккаунт Anthropic, но не через API-ключ или сторонние платформы вроде Amazon Bedrock или Google Cloud Agent Platform. Claude не поддерживает загрузку аудиофайлов для транскрибации через стандартный интерфейс, только диктовку в реальном времени. Подробнее о голосовых возможностях Claude читайте в статье про голосовой режим Claude с выбором моделей и интеграциями.

OpenAI переводит разработчиков с Assistants API на Responses API. Assistants API отключается 26 августа 2026 года. При миграции меняются названия полей использования токенов: Assistants API сообщает 34 токена промпта и 130 токенов завершения, Responses API - 17 входных токенов и 150 выходных токенов. Промпты в Responses API создаются только через дашборд, не через API. Если ваша система динамически создаёт ассистентов, это ограничение критично.

Локальные модели: офлайн-распознавание

Для проектов без интернета или с жёсткими требованиями к приватности используйте локальные модели. Vosk и Sherpa-ONNX работают на устройстве без внешних запросов. Vosk поддерживает русский язык и встраивается в Unity через нативные плагины. Задержка минимальна, но точность ниже, чем у Whisper large, особенно на шумных записях.

Локальные модели требуют включения нативных библиотек для каждой платформы: Android, iOS, Windows, macOS. Это увеличивает размер сборки и сложность поддержки, но убирает зависимость от сети и стоимость API-запросов.

Заключение: ключевые выводы и следующие шаги

Интеграция распознавания речи в Unity через Hugging Face API проходит четыре этапа: настройка UI, запись с микрофона, конвертация в WAV, отправка запроса. Для мультиязычных проектов выбирайте Whisper, для мобильных с одним языком - Wav2Vec2. Обрабатывайте ошибки 429 и 503 повторными попытками с экспоненциальной задержкой, проверяйте актуальность эндпоинтов на странице модели.

Следующий шаг: соберите минимальный прототип с кнопкой записи и выводом текста. Затем добавьте голосовые команды или диалоги с NPC. Если Hugging Face не покрывает требования по задержке, рассмотрите локальные модели Vosk или Sherpa-ONNX. Голосовой интерфейс в играх - растущий тренд, и базовые навыки интеграции ASR дают конкурентное преимущество уже сейчас. О том, почему голосовые интерфейсы становятся следующей большой платформой, читайте в анализе Voice Mode как предвестник смены парадигмы.

Подписаться на канал