228 lines
7.5 KiB
Python
228 lines
7.5 KiB
Python
import json5
|
||
import os
|
||
import shutil
|
||
#大模型配置
|
||
from qwen_agent.llm import get_chat_model
|
||
from openai import OpenAI
|
||
#兼容科大讯飞的openai_model
|
||
class openai_model():
|
||
def __init__(self,model={}):
|
||
self.config = model
|
||
self.client = OpenAI(
|
||
# 控制台获取key和secret拼接,假使控制台获取的APIPassword是123456
|
||
api_key= model["api_key"],
|
||
# 指向讯飞星火的请求地址
|
||
base_url = model["model_server"],
|
||
)
|
||
|
||
def chat(self,messages=[],stream=True,delta_stream=False):
|
||
self.messages = messages
|
||
if stream:
|
||
return self._chat_stream()
|
||
else:
|
||
return self._chat_no_stream()
|
||
|
||
def _chat_stream(self):
|
||
responses = self.client.chat.completions.create(
|
||
model=self.config["model"], # 指定请求的版本
|
||
messages=self.messages,
|
||
stream=True
|
||
)
|
||
|
||
content=""
|
||
for chunk in responses:
|
||
if chunk.choices and chunk.choices[0].delta.content:
|
||
#print(content)
|
||
content +=chunk.choices[0].delta.content
|
||
yield [{"content":content}]
|
||
|
||
|
||
def _chat_no_stream(self):
|
||
completion = self.client.chat.completions.create(
|
||
model=self.config["model"], # 指定请求的版本
|
||
messages=self.messages
|
||
)
|
||
return [{"content":completion.choices[0].message.content}]
|
||
|
||
|
||
##深度合并更新
|
||
def deep_update(source, overrides):
|
||
"""
|
||
将 overrides 字典递归合并到 source 字典中。
|
||
"""
|
||
for key, value in overrides.items():
|
||
if isinstance(value, dict) and key in source:
|
||
deep_update(source.get(key, {}), value)
|
||
else:
|
||
source[key] = value
|
||
return source
|
||
|
||
|
||
#1. 初始化默认配置参数
|
||
with open("conf/gcfg.default") as conf:
|
||
gcfg = json5.load(conf)
|
||
|
||
|
||
#2. 加载参数
|
||
try:
|
||
with open("conf/gcfg.conf") as conf:
|
||
gcfg0 = json5.load(conf)
|
||
gcfg = deep_update(gcfg,gcfg0) #深度合并更新
|
||
except:
|
||
pass
|
||
|
||
#3. 和并外部的配置参数
|
||
try:
|
||
#以外部配置的这个文件为准
|
||
with open(f'{gcfg["fs"]["path"]}/conf/gcfg.conf') as conf:
|
||
gcfg0 = json5.load(conf)
|
||
gcfg = deep_update(gcfg,gcfg0) #深度合并更新
|
||
except Exception as e:
|
||
print("配置文件有异常",e)
|
||
|
||
|
||
#.4 gcfg mem的部分
|
||
try:
|
||
with open(f'{gcfg["fs"]["path"]}/conf/gcfg_mem.conf') as conf:
|
||
gcfg_mem0 = json5.load(conf)
|
||
gcfg = deep_update(gcfg,gcfg_mem0) #深度合并更新
|
||
except:
|
||
try:
|
||
with open(f'{gcfg["fs"]["path"]}/conf/gcfg_mem.conf',"w+") as conf:
|
||
json5.dump(gcfg["mem"],conf,ensure_ascii=False)
|
||
except:
|
||
pass
|
||
|
||
#. 最后初始化
|
||
try:
|
||
#初始化路径
|
||
#配置文件路径
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/conf'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/conf')
|
||
|
||
#数据库路径
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/db'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/db')
|
||
|
||
#图片上传路径
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/img'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/img')
|
||
|
||
#视频上传路径
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/video'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/video')
|
||
|
||
#文档生成发布路径
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/pub'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/pub')
|
||
|
||
#上传文档的路径,文件中心默认的上传目录
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/文档'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/文档')
|
||
|
||
#复制智能体文件
|
||
try:
|
||
shutil.copy2("../mnt/Agents.json", f'{gcfg["fs"]["path"]}/文档/')
|
||
except:
|
||
pass
|
||
|
||
#个人文件夹,智能体对话个人上传的目录
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/个人文件夹'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/个人文件夹')
|
||
#个人文件夹-管理员
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/个人文件夹/管理员'):
|
||
os.makedirs(f'{gcfg["fs"]["path"]}/个人文件夹/管理员')
|
||
|
||
#初始化数据库文件
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/db/k_database.db'):
|
||
try:
|
||
shutil.copy2("../mnt/db/k_database.db", f'{gcfg["fs"]["path"]}/db/k_database.db') # 使用 copy2 保留元数据(如修改时间)
|
||
except:
|
||
try:
|
||
shutil.copy2("mnt/db/k_database.db", f'{gcfg["fs"]["path"]}/db/k_database.db') # 使用 copy2 保留元数据(如修改时间)
|
||
except:
|
||
pass
|
||
|
||
#初始化日志数据库文件
|
||
if not os.path.exists(f'{gcfg["fs"]["path"]}/db/logs.db'):
|
||
try:
|
||
shutil.copy2("../mnt/db/logs.db", f'{gcfg["fs"]["path"]}/db/logs.db') # 使用 copy2 保留元数据(如修改时间)
|
||
except:
|
||
try:
|
||
shutil.copy2("mnt/db/logs.db", f'{gcfg["fs"]["path"]}/db/logs.db') # 使用 copy2 保留元数据(如修改时间)
|
||
except:
|
||
pass
|
||
|
||
#初始化大模型
|
||
try:
|
||
with open(f'{gcfg["fs"]["path"]}/conf/llm.conf') as conf:
|
||
llm_conf = json5.load(conf)
|
||
except:
|
||
with open(f'conf/llm.default') as conf:
|
||
llm_conf = json5.load(conf)
|
||
with open(f'{gcfg["fs"]["path"]}/conf/llm.conf',"w+") as conf:
|
||
json5.dump(llm_conf,conf,ensure_ascii=False)
|
||
|
||
#大模型相关参数
|
||
gcfg["llm"]["ctx_size"] = int(gcfg["llm"]["ctx_size"])
|
||
gcfg["full_index"]["chunk_size"] = int(gcfg["full_index"]["chunk_size"])
|
||
gcfg["full_index"]["chunk_overlap"] = int(gcfg["full_index"]["chunk_overlap"])
|
||
|
||
|
||
#llm的通用参数设置
|
||
#ctx_size是字节,这里是token
|
||
#根据模型能力可以设置一个更大的值,负载超过此值,就不会给大模型发送数据了
|
||
generate_cfg = {
|
||
"max_input_tokens": int(gcfg["llm"]["ctx_size"]*1.5)+4090,
|
||
"temperature": float(gcfg["llm"]["temperature"]),
|
||
"top_p": float(gcfg["llm"]["top_p"]),
|
||
"top_k": int(gcfg["llm"]["top_k"]),
|
||
}
|
||
|
||
for cfg in llm_conf["llm_cfg"]:
|
||
if llm_conf["selected"]==cfg["id"]:
|
||
|
||
if cfg["id"]=="xunfei": #讯飞的单独处理
|
||
llm = openai_model({
|
||
# Use your own model service compatible with OpenAI API:
|
||
'model': cfg["name"],
|
||
'model_server': cfg["url"],
|
||
'api_key': cfg["api_key"],
|
||
'generate_cfg': generate_cfg
|
||
})
|
||
else:
|
||
llm = get_chat_model({
|
||
# Use your own model service compatible with OpenAI API:
|
||
'model': cfg["name"],
|
||
'model_server': cfg["url"],
|
||
'api_key': cfg["api_key"],
|
||
'generate_cfg': generate_cfg
|
||
})
|
||
break
|
||
except:
|
||
llm = get_chat_model({
|
||
# Use your own model service compatible with OpenAI API:
|
||
'model': 'Qwen/Qwen1.5-72B-Chat',
|
||
'model_server': 'http://127.0.0.1:8080/v1', # api_base
|
||
'api_key': 'EMPTY',
|
||
'generate_cfg': generate_cfg
|
||
})
|
||
|
||
#获取mem的实时的值
|
||
def get_gcfg_mem():
|
||
try:
|
||
with open(f'{gcfg["fs"]["path"]}/conf/gcfg_mem.conf') as conf:
|
||
gcfg_mem0 = json5.load(conf)
|
||
except:
|
||
gcfg_mem0 = gcfg["mem"]
|
||
return gcfg_mem0
|
||
|
||
#更新mem
|
||
def update_gcfg_mem(k1,k2,value):
|
||
gcfg_mem0 = get_gcfg_mem()
|
||
gcfg_mem0[k1][k2]=value
|
||
with open(f'{gcfg["fs"]["path"]}/conf/gcfg_mem.conf',"w+") as conf:
|
||
json5.dump(gcfg_mem0,conf,ensure_ascii=False)
|
||
|
||
|