From 8266979e91a1d1aa34d85cf932c75635b002939b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=84=E5=87=A4=E7=A7=91=E6=8A=80?= Date: Fri, 14 Feb 2025 10:24:02 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E5=A4=A7=E6=A8=A1=E5=9E=8Bollama=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.yaml | 7 ++++- core/providers/llm/ollama/ollama.py | 45 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 core/providers/llm/ollama/ollama.py diff --git a/config.yaml b/config.yaml index be05f592..184182a8 100644 --- a/config.yaml +++ b/config.yaml @@ -44,7 +44,7 @@ VAD: min_silence_duration_ms: 700 # 如果说话停顿比较长,可以把这个值设置大一些 LLM: - # 当前支持的type为openai、dify,可自行适配 + # 当前支持的type为openai、dify、ollama,可自行适配 AliLLM: # 定义LLM API类型 type: openai @@ -67,6 +67,11 @@ LLM: model_name: glm-4-flash url: https://open.bigmodel.cn/api/paas/v4/ api_key: 你的bigmodel api key + OllamaLLM: + # 定义LLM API类型 + type: ollama + model_name: qwen2.5 # 使用的模型名称,需要预先使用ollama pull下载 + base_url: http://localhost:11434 # Ollama服务地址 DifyLLM: # 定义LLM API类型 type: dify diff --git a/core/providers/llm/ollama/ollama.py b/core/providers/llm/ollama/ollama.py new file mode 100644 index 00000000..28c377d3 --- /dev/null +++ b/core/providers/llm/ollama/ollama.py @@ -0,0 +1,45 @@ +import logging +import requests, json +from core.providers.llm.base import LLMProviderBase + +logger = logging.getLogger(__name__) + + +class LLMProvider(LLMProviderBase): + def __init__(self, config): + + self.model_name = config.get("model_name") + self.base_url = config.get("base_url", "http://localhost:11434") + + def response(self, session_id, dialogue): + try: + # Convert dialogue format to Ollama format + prompt = "" + for msg in dialogue: + if msg["role"] == "system": + prompt += f"System: {msg['content']}\n" + elif msg["role"] == "user": + prompt += f"User: {msg['content']}\n" + elif msg["role"] == "assistant": + prompt += f"Assistant: {msg['content']}\n" + + # Make request to Ollama API + response = requests.post( + f"{self.base_url}/api/generate", + json={ + "model": self.model_name, + "prompt": prompt, + "stream": True + }, + stream=True + ) + + for line in response.iter_lines(): + if line: + json_response = json.loads(line) + if "response" in json_response: + yield json_response["response"] + + except Exception as e: + logger.error(f"Error in Ollama response generation: {e}") + yield "【Ollama服务响应异常】" From c60850ef3d8542f7f1d9d5c343730b5f284ba7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=84=E5=87=A4=E7=A7=91=E6=8A=80?= Date: Fri, 14 Feb 2025 10:29:37 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=B9=E9=94=99?= =?UTF-8?q?=E5=88=A4=E6=96=AD=20=E8=A7=A3=E5=86=B3ollama=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=9B=9E=E7=AD=94=E5=88=86=E5=89=B2=E5=90=8E?= =?UTF-8?q?=E6=9C=80=E5=90=8E=E4=B8=80=E5=8F=A5=E4=B8=BA=E7=A9=BA=EF=BC=8C?= =?UTF-8?q?speak=E4=B8=8D=E8=83=BD=E5=81=9C=E6=AD=A2=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/connection.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core/connection.py b/core/connection.py index 3f59762f..6972af76 100644 --- a/core/connection.py +++ b/core/connection.py @@ -138,9 +138,10 @@ class ConnectionHandler: # 处理剩余的响应 if start < len(response_message): segment_text = "".join(response_message[start:]) - self.recode_first_last_text(segment_text) - future = self.executor.submit(self.speak_and_play, segment_text) - self.tts_queue.put(future) + if len(segment_text) > 0: + self.recode_first_last_text(segment_text) + future = self.executor.submit(self.speak_and_play, segment_text) + self.tts_queue.put(future) self.llm_finish_task = True # 更新对话 @@ -159,6 +160,11 @@ class ConnectionHandler: try: self.logger.debug("正在处理TTS任务...") tts_file, text = future.result(timeout=10) + if text is None or len(text) <= 0: + continue + if tts_file is None: + self.logger.error(f"TTS文件生成失败: {text}") + continue self.logger.debug(f"TTS文件生成完毕,文件路径: {tts_file}") if os.path.exists(tts_file): opus_datas, duration = self.tts.wav_to_opus_data(tts_file) @@ -191,11 +197,11 @@ class ConnectionHandler: def speak_and_play(self, text): if text is None or len(text) <= 0: self.logger.info(f"无需tts转换,query为空,{text}") - return None + return None, text tts_file = self.tts.to_tts(text) if tts_file is None: self.logger.error(f"tts转换失败,{text}") - return None + return None, text self.logger.debug(f"TTS 文件生成完毕: {tts_file}") return tts_file, text