tayuLuc/dsh-ru-voice-input ↗★ 0
dsh-ru-voice-input
为输入框集成支持俄语的本地语音输入功能 适合需要俄语语音输入的用户,默认使用本地GigaAM模型识别。
安裝
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:tayuLuc/dsh-ru-voice-input說明文件
閱讀完整 README ↗dsh-ru-voice-input
Русский Voice input для DeepSeek Harness. Одна установка — и в композере микрофон, который сразу понимает русский.
Зачем он существует
Штатный плагин Voice input заточен под китайский: единственный провайдер — SenseVoice, и в релизном чекпойнте русского нет. Замер на Apple M1 (26.09.2026, 28.6 с русской речи): SenseVoice int8 вернул пустую расшифровку (0 слов, WER 100 %) и всё равно занял ~600 МБ RAM.
Замеры — на M1 / 8.6 ГБ, синтез речи macOS say -v Milena. Это смоук, а не бенчмарк.
Установка
dsh plugin --profile web add https://github.com/tayuLuc/dsh-ru-voice-input
Перезапустите Web UI. Дальше — кнопка микрофона между моделью и Send: нажать, разрешить доступ, записать, Stop. Расшифровка вставляется в черновик.
Первое использование скачивает и проверяет модель (ревизия и SHA-256 закреплены) в
~/.dsh/models/gigaam-v3-ctc/. SenseVoice не качается: в этом бандле его нет, у него нет
русского.
Если pnpm ругается на ERR_PNPM_IGNORED_BUILDS — разрешите сборку нативного рантайма в
~/.dsh/profiles/ /pnpm-workspace.yaml:
allowBuilds:
onnxruntime-node: true
koffi: true
Что внутри
Один пакет, четыре слоя, формально те же четыре строки, что у штатного Voice input:
| Слой | Что это |
|---|---|
./lib/registry.js | форк speech-to-text с починенным configure() |
./lib/gigaam/index.js | провайдер GigaAM v3 CTC на onnxruntime-node или transcribe-cpp |
@deepseek-ai/dsh-experimental-api-speech-to-text | мост браузер↔хост, штатный |
@deepseek-ai/dsh-experimental-client-ui-voice-input | кнопка микрофона, штатная |
Дефолты: распознаватель gigaam-v3-ctc-local, язык ru. Свежий профиль работает без кликов.
Слои 1 и 2 заданы относительными спецификаторами — загрузчик их резолвит внутри пакета. Так бандл остаётся самодостаточным: пакет, поставленный из git, не может зависеть от собственных подкаталогов.
Движки
Движок выбирается конфигом engine, по умолчанию e2e. Замер на этом хосте (Apple M1),
прогретый, русская речь 5 с и 28.6 с:
engine | Рантайм | RTF (5 с) | RTF (28.6 с) | Пунктуация |
|---|---|---|---|---|
e2e (по умолчанию) | MLX, gigaam-mlx через Python-сайдкар | 0.027 | 0.017 | есть |
metal | GGUF Q8_0, transcribe-cpp | — | 0.016 | нет |
onnx | int8, onnxruntime-node | 0.038 | 0.043 | нет |
Только e2e даёт пунктуацию и заглавные. Словарь CTC-голов GigaAM — 34 токена: ▁, 32
русские буквы и ``. Знаков препинания в нём нет физически, поэтому metal и onnx не
могут их выдать ни при какой настройке.
Пример одного и того же места: панель а показывает (CTC) против Панель A показывает (e2e).
Требования движка e2e
Python ≥ 3.10 с установленным gigaam-mlx и ffmpeg в PATH:
uv venv ~/.dsh/venvs/gigaam-mlx --python 3.12
uv pip install --python ~/.dsh/venvs/gigaam-mlx/bin/python \
"gigaam-mlx @ git+https://github.com/aystream/gigaam-mlx.git"
Путь ищется так: поле e2ePythonPath, иначе $GIGAAM_MLX_PYTHON, иначе
/venvs/gigaam-mlx/bin/python. Веса модель качает сама в кэш Hugging Face.
Цена первого запроса. В свежем процессе MLX компилирует пайплайн: первый ответ ~1.7 с
против 0.13 с прогретого, дальше 0.027 RTF. Поэтому idleTimeoutMs: 0 ставить не стоит:
воркер должен переживать паузу между записями.
Почему реестр форкнут
Штатный configure() проверяет текущий язык против нового провайдера:
const id = patch.providerId ?? this.config.defaultProvider.get();
this.selectedProvider(id, patch.language ?? this.config.language.get());
Из-за этого смена распознавателя невозможна, когда сохранённый язык не входит в список нового провайдера. В настройках это выглядит как «выбрал — откатило», и выхода нет: выбрать русский можно только у провайдера, который русский уже поддерживает.
Фикс: голое переключение провайдера берёт язык, который новый провайдер принимает, — сначала сохранённый, иначе первый в его списке. Явно заданный язык по-прежнему проверяется и по-прежнему отвергается вслух.
Контракт сервиса не изменён: имя speechToText, схема конфига и все методы те же, поэтому
штатные мост и UI работают против форка без изменений.
Проверка
npm test # реестр: переключение провайдера, 11 проверок
node test/provider.mjs # провайдер: регистрация, prepare, расшифровка
У провайдера есть отрицательный контроль: тишина обязана дать пустой текст, иначе сломанная модель прошла бы как рабочая.
Живой замер движка:
node test/provider.mjs ~/.dsh/models/gigaam-v3-ctc e2e # или metal, onnx
node scripts/selftest.mjs ~/.dsh/models/gigaam-v3-ctc onnx # замер только Node-движков
Что дальше
RNNT вместо CTC в движке e2e. Сейчас по умолчанию ctc — он быстрее. rnnt заявлен
точнее (~77× против ~330× realtime у автора на M2 Max), обе ветки с пунктуацией. Переключается
конфигом e2eModel, без переустановки.
Память. По умолчанию воркер освобождается через 120 с простоя. idleTimeoutMs: 0
держит его загруженным постоянно — на ноутбуке этого стоит избегать.
Лицензия
MIT. Форк реестра — производная от @deepseek-ai/dsh-experimental-speech-to-text 0.1.7-rc.2.
Веса модели не входят в поставку: провайдер тянет их сам по закреплённой ревизии.