From 80b10ca9709b6a0ec35a441707b7dc76fe1a9937 Mon Sep 17 00:00:00 2001 From: fanpt <320622572@qq.com> Date: Fri, 25 Jul 2025 15:27:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 8 ++--- lipreal.py | 2 +- llm.py | 102 +++++++++++++++++++++++++++++++---------------------- 3 files changed, 65 insertions(+), 47 deletions(-) diff --git a/app.py b/app.py index f8a57ac..7e8ded6 100644 --- a/app.py +++ b/app.py @@ -335,8 +335,8 @@ if __name__ == '__main__': parser.add_argument('--customvideo_config', type=str, default='', help="custom action json") parser.add_argument('--tts', type=str, default='edgetts', help="tts service type") #xtts gpt-sovits cosyvoice - parser.add_argument('--REF_FILE', type=str, default="zh-CN-YunxiaNeural") - parser.add_argument('--REF_TEXT', type=str, default=None) + parser.add_argument('--REF_FILE', type=str, default="input/doubao.wav") + parser.add_argument('--REF_TEXT', type=str, default="刚进直播间的宝子们,左上角先点个关注,点亮咱们家的粉丝灯牌!我是你们的主播陈婉婉,今天给大家准备了超级重磅的福利") parser.add_argument('--TTS_SERVER', type=str, default='http://127.0.0.1:9880') # http://localhost:9000 # parser.add_argument('--CHARACTER', type=str, default='test') # parser.add_argument('--EMOTION', type=str, default='default') @@ -370,9 +370,9 @@ if __name__ == '__main__': elif opt.model == 'wav2lip': from lipreal import LipReal,load_model,load_avatar,warm_up logger.info(opt) - model = load_model("./models/wav2lip.pth") + model = load_model("./models/wav2lip384.pth") avatar = load_avatar(opt.avatar_id) - warm_up(opt.batch_size,model,256) + warm_up(opt.batch_size,model,384) elif opt.model == 'ultralight': from lightreal import LightReal,load_model,load_avatar,warm_up logger.info(opt) diff --git a/lipreal.py b/lipreal.py index 128a749..0dbba32 100644 --- a/lipreal.py +++ b/lipreal.py @@ -36,7 +36,7 @@ import torch.multiprocessing as mp from lipasr import LipASR import asyncio from av import AudioFrame, VideoFrame -from wav2lip.models import Wav2Lip +from wav2lip.models384.wav2lip import Wav2Lip from basereal import BaseReal #from imgcache import ImgCache diff --git a/llm.py b/llm.py index 857084d..6ef87f6 100644 --- a/llm.py +++ b/llm.py @@ -1,48 +1,66 @@ +import re import time -import os +import requests +import json from basereal import BaseReal from logger import logger -def llm_response(message,nerfreal:BaseReal): +def llm_response(message: str, nerfreal: BaseReal): start = time.perf_counter() - from openai import OpenAI - client = OpenAI( - # 如果您没有配置环境变量,请在此处用您的API Key进行替换 - api_key=os.getenv("DASHSCOPE_API_KEY"), - # 填写DashScope SDK的base_url - base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) - end = time.perf_counter() - logger.info(f"llm Time init: {end-start}s") - completion = client.chat.completions.create( - model="qwen-plus", - messages=[{'role': 'system', 'content': 'You are a helpful assistant.'}, - {'role': 'user', 'content': message}], - stream=True, - # 通过以下设置,在流式输出的最后一行展示token使用信息 - stream_options={"include_usage": True} - ) - result="" + logger.info(f"message:{message}") + url = "http://192.168.10.70:11434/api/chat" + data = { + "model": "qwen3:30b-a3b", + "messages": [ + {"role": "system", "content": "你叫小苏,贵州人,带有轻微贵州口音,现在正在直播,你的人设是带货主播,你现在卖的产品是酱酒,任务是消除消费者对假酒的顾虑。"}, + {"role": "user", "content": f"{message}\n不可以输出表情包/no_think"} + ], + "stream": True + } + + response = requests.post(url, json=data, stream=True) + logger.info(f"Ollama init time: {time.perf_counter() - start:.2f}s") + + result = "" + full_answer = "" first = True - for chunk in completion: - if len(chunk.choices)>0: - #print(chunk.choices[0].delta.content) - if first: - end = time.perf_counter() - logger.info(f"llm Time to first chunk: {end-start}s") - first = False - msg = chunk.choices[0].delta.content - lastpos=0 - #msglist = re.split('[,.!;:,。!?]',msg) - for i, char in enumerate(msg): - if char in ",.!;:,。!?:;" : - result = result+msg[lastpos:i+1] - lastpos = i+1 - if len(result)>10: - logger.info(result) - nerfreal.put_msg_txt(result) - result="" - result = result+msg[lastpos:] - end = time.perf_counter() - logger.info(f"llm Time to last chunk: {end-start}s") - nerfreal.put_msg_txt(result) \ No newline at end of file + think_tag_pattern = re.compile(r"", re.IGNORECASE) + punctuation = ",.!;:,。!?:;" + + for line in response.iter_lines(): + if not line: + continue + + try: + json_data = json.loads(line.decode("utf-8")) + except json.JSONDecodeError: + continue + + # 如果有结束标志,可以在此处判断并 break + # if json_data.get("done"): + # break + + msg = json_data.get("message", {}).get("content", "") + msg = think_tag_pattern.sub("", msg) + if not msg: + continue + + full_answer += msg + + if first: + logger.info(f"Ollama time to first chunk: {time.perf_counter() - start:.2f}s") + first = False + + lastpos = 0 + for i, char in enumerate(msg): + if char in punctuation: + result += msg[lastpos:i+1] + lastpos = i+1 + if len(result) > 10: + logger.info(result) + nerfreal.put_msg_txt(result) + result = "" + result += msg[lastpos:] + + if result: + nerfreal.put_msg_txt(result) \ No newline at end of file