Skip to content

Releases: JMS1717/ming-voice

v1.6.0: native Linux (AMD and NVIDIA), Jarvis mode, smarter Home Assistant

Choose a tag to compare

@JMS1717 JMS1717 released this 22 Oct 16:06

Ming Voice now runs natively on Linux, on AMD and NVIDIA GPUs, with a one-line install. This release also adds Jarvis mode, much better Home Assistant control, steadier built-in voices, and a move to PyTorch 2.11.

Linux

Open a terminal and paste:

curl -fsSL https://raw.githubusercontent.com/JMS1717/ming-voice/main/install.sh | bash
  • Distros: Arch, CachyOS, EndeavourOS, Manjaro, Ubuntu, Debian, Pop!_OS, Mint, Fedora, Nobara and openSUSE. Others work too if they have git and curl.
  • AMD needs no ROCm install. PyTorch's ROCm 7.2 build carries its own libraries, so the standard amdgpu driver that comes with your kernel is enough. Supported cards are the RX 6800 and newer, the RX 7000 and 9000 series, and Radeon PRO.
  • NVIDIA needs only your distro's driver; PyTorch brings CUDA 12.8.
  • What the installer does:
    • Installs what's missing (git, curl, openssl, PortAudio) with your package manager.
    • Picks the right GPU. When there's also an integrated GPU, it uses the big one.
    • Sets up cards PyTorch doesn't list as their closest supported sibling.
    • Adds you to the render group.
    • Puts Ming Voice in your app menu.
    • Running it again skips the finished steps.
  • The ming-voice command starts the server in the background, waits for the model, and opens the app. You can also:
    • --always-on: wake word, no browser
    • --phone: use it from your phone
    • --autostart: start at login
    • --stop, --status, --logs

Tested in fresh CachyOS, Arch, Ubuntu 24.04, Debian 13, Fedora and openSUSE Tumbleweed installs, plus CUDA on a real NVIDIA card.

PyTorch 2.11 and ROCm 7.2

  • Every platform moves from PyTorch 2.8 to 2.11:
    • ROCm 7.2 on Linux
    • AMD's ROCm 7.2.4 build in WSL
    • CUDA 12.8 on NVIDIA
  • On Windows, re-run the installer (or bash setup_env.sh) to upgrade. Speed and output match the old version.

Jarvis mode

  • Pick Jarvis (robot butler) under Settings → Persona. You get a dry-witted British butler with its own designed voice and the wake word "Jarvis".
  • Even its tool confirmations are in character.
  • The voice is an original design, not a copy of anyone's.

Home Assistant

  • Media: pause, skip, volume and "what's playing?" for speakers and TVs.
  • Lights: colours, warm white and "dimmer".
  • Car: climate, temperature and defrost.
  • Follow-ups work: "now turn it off", "and the living room too".
  • Rooms: "turn off the lights" means the lights in the room the device is in.
  • Two commands at once: "turn off the desk lamp and lock the car".
  • For later: "turn off the lights in 20 minutes", "start the vacuum at 9 am".
  • Music Assistant: "play some jazz on the kitchen speaker".
  • Heads-ups when a lock or garage door is left open at night, or the vacuum gets stuck or finishes.
  • Clear commands go straight to Home Assistant, and your own words are used, not the model's rewording.

Also new

  • Ending the conversation: say "that's all, bye" and it ends the conversation, or goes back to sleep in wake-word mode.
  • Steadier built-in voices: voice anchors keep them consistent from reply to reply, and numbers from 21 to 99 are said as words.
  • Windows installer: one step with install.ps1 / Install.cmd, including experimental NVIDIA support.
  • Tests: dev/test_ha_model.py checks the model's Home Assistant calls.

v1.5.0: lists, memory, and a voice that reads numbers right

Choose a tag to compare

@JMS1717 JMS1717 released this 21 Oct 16:44

Ming Voice now keeps shopping and to-do lists, remembers things you tell it, picks up the conversation after a restart, and reads numbers, money and units aloud the way you'd say them.

Lists

  • New lists tool. Try "add milk, eggs and bread to my shopping list", "what's on my to-do list?", "I bought the eggs" or "clear my shopping list".
  • It handles shopping, to-do, or any list you name. "Groceries" means the shopping list.
  • Duplicates and plurals are handled: "egg" removes "eggs".
  • Lists are kept in .lists.json on the server.

Memory

  • New memory tool. Say "remember that I parked on level 3", and days later ask "where did I park?". Say "forget where I parked" to remove it.
  • Up to 40 facts are kept in .memory.json and given to the model in every conversation.

Replies that claim an action are made true

  • Sometimes the model says it changed a list or forgot something without calling the tool, for example "The eggs are off your list".
  • That call is now made for it, so what it said actually happened.
  • If the call doesn't succeed (say the item wasn't on the list), the reply tells you so.

Survives restarts

  • The conversation is saved in .conversation.json after every turn.
  • A server that restarts within 30 minutes carries on where it left off. Set the window with MING_RESUME_S.
  • New chat clears it.

Speaks numbers and symbols properly

These are rewritten into words before they're spoken:

  • "240 × 37" and "3x"
  • "-5°C"
  • score and year ranges ("24-17", "2025–2026")
  • money ("$1,299.99", "$5.5 million", "£3.50")
  • speeds ("12 km/h", "5 mph")
  • "12:00 PM"
  • simple fractions, "&", and hyphenated words such as "Wi-Fi"

Each rule was checked by speaking it and transcribing it back.

Better routing

  • Requests to research or compare what's best this year now reliably use web search.

Tests

  • dev/test_speech_text.py: offline checks of the spoken-text rewriting.
  • dev/test_tools.py: now covers lists and memory, offline.

v1.4.0 — smarter tool use, listenable answers, self-restarting server

Choose a tag to compare

@JMS1717 JMS1717 released this 21 Oct 16:13

Ming Voice now answers more of what you ask itself, uses tools only when they help, keeps answers short enough to listen to, and restarts by itself after a crash.

Better answers, fewer needless tool calls

  • The assistant knows its name. The persona is now "Ming". Before, "Hey Ming" in your question sometimes made it look "Ming" up: in Hermes, in Jellyfin, or on the clock.
  • The time and date need no tool. Each reply starts from a private note of the local date and time, so "what time is it?" and "what's today's date?" are answered at once. get_current_time is for other time zones.
  • Jellyfin is only used when you talk about watching or listening. It only starts playback when you say to (play, watch, put on, listen, ...). "Tell me a joke" no longer plays a show with "joke" in its title.
  • Replies that forget the tools are caught. Sometimes the model says it can't look things up ("I don't have access to real-time data..."). Now the start of such a reply is held back before it is spoken, and the turn becomes a web search (or a weather lookup) instead.
  • Answers you can listen to.
    • An answer from search or weather results ends after a few sentences.
    • Any other answer ends after about 30 seconds of speech, unless you asked for something long: a story, a recipe, steps, "in detail", and so on.
    • A reply that reaches the length limit now finishes its sentence instead of stopping mid-word.

Hermes only when you ask for it

  • ask_hermes now runs only when you say "Hermes" ("ask Hermes to ..."). This is checked against what you actually said.
  • MING_HERMES_AUTO=1 brings back the old behaviour: Ming hands Hermes anything its own tools can't do.

Timers

  • Repeating alarms. A timer that goes off is said again every minute, twice more, until you say something or press stop. Set the repeats with MING_ALARM_REPEATS (0 for once only) and the interval with MING_ALARM_REPEAT_S.
  • Wording fixes. "Your timer for 10 minutes is done" replaces "Your 10 minutes timer is done". A reminder written as "time to stretch" is no longer said as "Time to time to stretch".

Reliability

  • Self-restarting server.
    • run.sh restarts the server 10 s after a crash when MING_SUPERVISE=1. The always-on launcher sets this.
    • A GPU error that leaves the device unusable now exits the server, so it comes back on a fresh one.
    • A second copy started by mistake exits with a clear message instead of looping.
  • Weather lookups retry once when the weather service is slow or failing, and remember place lookups, which saves a round trip.

Always-on client

  • Check your microphones: python windows\ming_client.py --test-mics lists every input device with its level and flags silent ones. Use it to pick input_device for .client.json.
  • Silent-mic warning: the client log now names the microphone and speakers in use. It also warns when the mic has picked up nothing for 10 minutes, for example when it is muted or the wrong device is selected.

Tests

  • dev/test_routing.py speaks 17 everyday questions and checks which tools are used for each. General knowledge must use no tool, the time and date must come from the note, and research must use web search.

v1.3.0 — always on: desk client, announcements, confirmations

Choose a tag to compare

@JMS1717 JMS1717 released this 21 Oct 14:21

Ming Voice now works as an always-on home assistant: no browser tab, announcements from Home Assistant, and a spoken check before risky actions.

Always on, without a browser

  • windows\ming_client.py is a background client that uses the PC's own microphone and speakers, in wake-word mode ("Hey Ming, ..."). Timer alarms and announcements play through the speakers too.
  • Start it: run windows\Ming Voice (always on).cmd. It starts the server minimized, plus phone access and the client.
  • Start at sign-in: windows\install_autostart.ps1 now sets up this always-on version. Use -Browser for the previous behaviour (open the app in the browser).
  • Speakers vs. headset: on speakers the mic is muted while Ming talks, so it never answers itself. With a headset, set "barge_in": true to be able to talk over it.
  • Sharing with the phone: opening the app on your phone takes over; the PC client takes the conversation back by itself 15 s after the phone app is closed.
  • Settings go in .client.json (not committed): wake word, voice, location, and mic/speaker devices.
  • Needs: Python for Windows with pip install sounddevice websockets numpy.

Announcements

  • From Home Assistant: Ming listens on Home Assistant's event bus. An automation with an event action (ming_announce, message: Someone is at the front door.) makes it say that. No integration, configuration.yaml change or HA restart is needed.
  • From anything else: send POST /api/announce with {"message": "The washer is done."}.
  • How they're said: each one waits for a quiet moment and plays a short chime first. Announcements that can't be said within ttl (5 minutes by default) are dropped.

Confirmation for risky actions

  • Unlocking, opening a garage door or gate, and disarming an alarm get a question first: "Just to be sure: do you want me to unlock the front door?"
  • The action only happens on a yes in your next turn, within a minute. Exactly what you were asked about is what runs.
  • A yes in the same reply that asked doesn't count, and neither does a yes to a different device.
  • Questions ("is the garage open?") and locking/closing aren't asked about. MING_CONFIRM_RISKY=0 turns this off.

Context

  • When the context fills up, it's rebuilt from the conversation as text between turns, while nobody is talking (about 0.5 s). Before, this happened at the start of your next reply and delayed it. The first two exchanges and the most recent ones are kept.
  • Long prompts are processed in 512-token chunks, which bounds their GPU memory.
  • Context size: 8k stays the default on 24 GB cards and 16k is used from 32 GB; MING_MAX_CTX overrides it. A bigger context doesn't slow short conversations, but on a 24 GB card 16k leaves the GPU libraries too little working memory next to the voice model.

Fixes

  • The Windows launcher's "is it already running?" check timed out because PowerShell 5 tries IPv6 for localhost first. When that happened it tried to start a second server.

Ming Voice 1.2: wake word, timers, Brave Search

Choose a tag to compare

@JMS1717 JMS1717 released this 21 Oct 13:18

This release is a step toward an always-on assistant: a wake word, native timers and reminders, and better web search.

Wake word

  • New Wake word turn-taking mode (Settings). It listens all the time but only answers speech that starts with its name, e.g. "Hey Ming, turn off the lamp". You can also say just "Hey Ming", wait for the chime, then talk.
  • Follow-up window: for 8 s after each reply you can keep talking without the wake word.
  • No training, no extra model: the name is checked by Ming's own speech recognition on the first 1.6 s of each utterance, while you're still talking. Answers start as fast as in hands-free mode. Any name works; set it in Settings.
  • Timer alarms and Hermes results are announced whether it's asleep or awake.

Timers and reminders

  • A native timer tool: "set a timer for 10 minutes", "remind me to call mom at 5 pm", "how long is left?", "cancel the pasta timer".
  • Understands durations ("an hour and a half", "90 seconds") and clock times ("5:30 pm", "tomorrow at 9", "Friday at noon").
  • When one goes off, the page chimes and says it, e.g. "Time to call mom.".
  • Timers are saved to disk, so they survive a restart. One that went off while the server was down is announced late rather than lost.

Web search

  • Optional Brave Search (.brave_key or MING_BRAVE_KEY; there's a free tier) for fresher, more reliable web results. DuckDuckGo stays the fallback, and news questions still use DuckDuckGo News, which ranks headlines better.
  • Answers after a tool call are now kept to one or two spoken sentences: no bulleted lists, no "want me to dig deeper?".

Other

  • windows/install_autostart.ps1 starts Ming Voice when you sign in to Windows. It only affects your account; run it with -Remove to undo.
  • New dev/test_wake.py, plus timer checks in dev/test_tools.py.

Ming Voice 1.1: tools, Home Assistant, Jellyfin, Hermes

Choose a tag to compare

@JMS1717 JMS1717 released this 21 Oct 12:42

The assistant can now use tools while it talks, and the model decides when to call them. General questions and small talk still get an instant answer with no tool call.

New

  • Web search (DuckDuckGo, no key) for news, prices, scores and recent events. The reply shows what was searched and the sources.
  • Weather (Open-Meteo, no key): current conditions and a 3-day forecast. Set "Your location" in Settings to use it as the default.
  • Calculator and clock for exact arithmetic and the current date and time.
  • Home Assistant control through HA's own Assist API. Device names, aliases and areas work just as they do in HA, and only entities exposed to voice assistants can be touched.
  • Jellyfin: search the library, play (a series continues at the next unwatched episode), pause, resume, stop, skip, and ask "what's playing?" on any open Jellyfin player.
  • Hermes Agent delegation: "ask Hermes to …" hands bigger jobs to a Hermes Agent running in the background. The answer is spoken when it's ready, even if the conversation has moved on.
  • Tools that change something (Home Assistant, Jellyfin, Hermes) never run from a speculative reply. They wait until your turn has really ended.
  • A cached system prompt, so the first reply after a reconnect starts quickly.

Fixes

  • Memory no longer grows during long sessions (MALLOC_ARENA_MAX=2).
  • Phone links opened from another app no longer land on the access-denied page, and that page now has a box to enter the key.

Setup

Each integration is optional and is turned on by adding a git-ignored file next to server.py: .ha_token / .ha_url, .jellyfin.json, .hermes.json. The README's Tools section shows the format for each.

Tested with dev/test_tools.py (tool choice, answers, delegation) and dev/test_api.py (14/14).

Ming Voice 1.0

Choose a tag to compare

@JMS1717 JMS1717 released this 21 Oct 11:37

First release of Ming Voice: a fully local, low-latency speech-to-speech voice assistant built on Ming-3.0-audio-tiny, running on AMD Radeon GPUs (ROCm 7.2 in WSL2). No audio leaves the machine.

Highlights

  • ~0.23 s from the end of your speech to the first audio (median, RX 7900 XTX), measured from the last audible sound of the question
  • Smart turn detection (Smart Turn v3) with speculative replies generated during your pause, plus resume after a pause: if you carry on talking right after it starts answering, the answer is withdrawn and everything is answered as one turn
  • Barge-in that works on a speakerphone: the server recognises its own voice coming back through the mic and stops only for yours (stops ~0.23 s after you start talking)
  • Use it from your phone over HTTPS on your home network: QR code, access key, installable web app, conversation restored after reconnects
  • OpenAI-compatible API: /v1/audio/speech, /v1/audio/transcriptions, /v1/chat/completions (audio in and out), /v1/models
  • 7 built-in voices plus voice cloning from a 5–15 s sample; English and Chinese
  • 16 GB cards supported via int8 MoE experts (auto below 23 GB VRAM, ~12.5 GB total)

Performance (RX 7900 XTX, 24 GB)

End of speech → first audio ~0.23 s median
Thinker decode ~115 tokens/s
Talker ~0.3× real time
Startup ~30 s
VRAM ~20.5 GB bf16 · ~12.5 GB int8 experts

Since the first commit

  • Speed: fused Triton RMSNorm/MoE router, grouped MoE prefill kernels, graph-captured prefill, energy-based pause timing and earlier speculation took end-of-speech-to-audio from ~0.56 s to ~0.23 s
  • Echo guard locks onto the echo delay before trusting a match (fixes a rare swallowed barge-in)
  • Server memory no longer grows per conversation (glibc arenas capped in run.sh); ~0.6 GB less RAM without idle compile workers
  • Phone fixes: login links opened from other apps, message bar position, updates picked up on reload

Install

See the README: Windows 11 + WSL2 Ubuntu 24.04, an AMD GPU with 16 GB+ VRAM, ~30 GB disk.