diff --git a/README.md b/README.md index 4ce9067..76787d2 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,89 @@ -# ollama-voice-mac -A completely offline voice assistant using Mistral 7b via Ollama and Whisper speech recognition models. This builds on the [excellent work of maudoin](https://github.com/maudoin/ollama-voice) by adding Mac compatibility with various improvements. +# x-Ollama-Voice-Mac +一款完全离线运行的语音助手,集成了 Whisper、Ollama 和 pyttsx3 模型,支持离线语音识别、自然语言处理及文本转语音(TTS)功能。 +结合 **Mistral 7b**(通过 Ollama 实现)和 **Whisper** 语音识别模型构建而成。此项目基于 [maudoin 的优秀工作](https://github.com/apeatling/ollama-voice-mac),添加了对 Mac 的兼容性并进行了一系列改进。 -https://github.com/apeatling/ollama-voice-mac/assets/1464705/996abeb7-7e99-451b-8d3b-feb3fecbb82e +https://github.com/apeatling/ollama-voice-mac/assets/1464705/996abeb7-7e99-451b-8d3b-feb3fecbb82e -## Installing and running +--- -1. Install [Ollama](https://ollama.ai) on your Mac. -2. Download the Mistral 7b model using the `ollama pull mistral` command. -3. Download an [OpenAI Whisper Model](https://github.com/openai/whisper/discussions/63#discussioncomment-3798552) (base.en works fine). -4. Clone this repo somewhere. -5. Place the Whisper model in a /whisper directory in the repo root folder. -6. Make sure you have [Python](https://www.python.org/downloads/macos/) and [Pip](https://pip.pypa.io/en/stable/installation/) installed. -7. For Apple silicon support of the PyAudio library you'll need to install [Homebrew](https://brew.sh) and run `brew install portaudio`. -8. Run `pip install -r requirements.txt` to install. -9. Run `python assistant.py` to start the assistant. +## 安装与运行 +### 0. 在mac上安装python的虚拟环境 +python3.11 -m venv myenv_311 +source myenv_311/bin/activate +deactivate -## Improving the voice +### 1. 安装 Ollama +在 Mac 上安装 [Ollama](https://ollama.ai)。 -You can improve the quality of the voice by downloading a higher quality version. These instructions work on MacOS 14 Sonoma: +### 2. 下载 Mistral 7b 模型 +运行以下命令下载模型: +```bash +ollama pull mistral +``` -1. In System Settings select Accessibility > Spoken Content -2. Select System Voice and Manage Voices... -3. For English find "Zoe (Premium)" and download it. -4. Select Zoe (Premium) as your System voice. +### 3. 下载 Whisper 模型 +访问 [Whisper 模型库](https://github.com/openai/whisper/discussions/63#discussioncomment-3798552),选择适合的模型(`base` 即可)。 -## Other languages -You can set up support for other languages by editing `assistant.yaml`. Be sure to download a different Whisper model in your language and change the default `modelPath`. +### 4. 克隆本项目 +将项目代码克隆到本地计算机: +```bash +git clone <仓库地址> +``` + +### 5. 配置 Whisper 模型路径 +将 Whisper 模型放入项目根目录的 `/whisper` 文件夹中。 + +### 6. 安装 Python 和 Pip +确保已安装 [Python](https://www.python.org/downloads/macos/) 和 [Pip](https://pip.pypa.io/en/stable/installation/)。 + +### 7. 配置 PyAudio 库(Apple Silicon 特别步骤) +对于 Apple Silicon 用户,需安装 **Homebrew** 并运行以下命令: +```bash +brew install portaudio +``` + +### 8. 安装依赖 +运行以下命令安装所需依赖: +```bash +pip install -r requirements.txt +``` + +### 9. 启动助手 +运行以下命令启动语音助手: +```bash +python assistant.py +``` + + +### 10. 中间使用的要点: +语音识别:使用 Whisper 模型进行本地语音识别,完全离线运行。 +自然语言处理:使用 Ollama 平台运行 Mistral 7b 模型,实现高效的本地大语言模型推理,无需联网。 +文本转语音(TTS):基于 pyttsx3 实现的离线文本语音合成功能,支持多种语言和语音优化。但是 pyttsx3 太机械了 增加了edge-tts + + +--- + +## 提升语音质量 + +在 MacOS 14 Sonoma 中,可以通过以下步骤提升语音质量: + +1. 打开 **系统设置** > **辅助功能** > **语音内容**。 +2. 选择 **系统语音** 并点击 **管理语音**。 +3. 在英文语音中找到 **"Zoe (Premium)"** 并下载。 +4. 下载完成后,将系统语音更改为 **Zoe (Premium)**。 + +--- + +## 支持其他语言 + +要支持其他语言,可以通过以下方式配置: + +1. 编辑 `assistant.yaml` 文件。 +2. 下载目标语言的 Whisper 模型并将其路径更新到 `modelPath` 配置项。 + +**示例(中文配置)**: +- 下载适合中文的 Whisper 模型,例如 `medium.zh`。 +- 在 `assistant.yaml` 中将 `modelPath` 修改为下载的模型路径,例如: + ```yaml + modelPath: /path/to/medium.zh.pt + ``` \ No newline at end of file diff --git a/assistant.png b/assistant.png index 6b489fa..ecf0baa 100644 Binary files a/assistant.png and b/assistant.png differ diff --git a/assistant.py b/assistant.py index 744acb1..f4a3ace 100644 --- a/assistant.py +++ b/assistant.py @@ -45,7 +45,10 @@ class Assistant: def __init__(self): logging.info("Initializing Assistant") self.config = self.init_config() - + + # 预初始化 pygame mixer,避免每次语音播放时的初始化开销 + pygame.mixer.init() + programIcon = pygame.image.load('assistant.png') self.clock = pygame.time.Clock() @@ -271,30 +274,32 @@ class Assistant: logging.info(f"Using edge-tts with voice: {self.edge_voice}") communicate = edge_tts.Communicate(text, self.edge_voice) - # 添加调试信息 - logging.info("Starting audio generation...") - await communicate.save("temp_speech.mp3") - logging.info("Audio file generated successfully") + # 使用异步方式并行处理音频生成 + audio_task = asyncio.create_task(communicate.save("temp_speech.mp3")) + + # 在音频生成的同时执行其他初始化 + if not pygame.mixer.get_init(): + pygame.mixer.init() + + # 等待音频生成完成 + await audio_task if not os.path.exists("temp_speech.mp3") or os.path.getsize("temp_speech.mp3") == 0: raise Exception("Generated audio file is empty or does not exist") - pygame.mixer.init() pygame.mixer.music.load("temp_speech.mp3") pygame.mixer.music.play() while pygame.mixer.music.get_busy(): - pygame.time.wait(100) - - pygame.mixer.quit() + await asyncio.sleep(0.1) # 使用异步等待替代 pygame.time.wait + # 不要每次都退出 mixer,只清理文件 if os.path.exists("temp_speech.mp3"): os.remove("temp_speech.mp3") except Exception as e: logging.error(f"An error occurred during edge-tts speech playback: {str(e)}") logging.error(f"Voice being used: {self.edge_voice}") - # 如果 edge-tts 失败,回退到 pyttsx3 logging.info("Falling back to pyttsx3...") self.tts_engine.say(text) self.tts_engine.runAndWait() @@ -305,9 +310,7 @@ class Assistant: def play_speech(): try: - logging.info("Starting speech playback") - time.sleep(0.5) # Short delay before speaking - + # 移除不必要的延迟 if self.config.tts.engine == "edge-tts": asyncio.run(self.edge_tts_speak(text)) else: # pyttsx3 @@ -318,7 +321,8 @@ class Assistant: except Exception as e: logging.error(f"An error occurred during speech playback: {str(e)}") - speech_thread = threading.Thread(target=play_speech) + # 使用守护线程,这样主程序退出时不会被阻塞 + speech_thread = threading.Thread(target=play_speech, daemon=True) speech_thread.start()