Spaces:
Runtime error
Runtime error
''' | |
重要说明: | |
1. 需要确认import的包是否是requirements.txt中的版本,否则会出现不兼容的情况。 | |
2. 在LAN中如何访问Gradio app: | |
1. 在Gradio中制定demo.launch(height='1500px', server_name="0.0.0.0", server_port=7860, auth=auth_list, auth_message="欢迎使用中交建财务共享中心企业大语言模型平台", share=False).queue() | |
2. 在另外一台电脑上,通过http://http://192.168.1.104:7860/ (其中http://192.168.1.104是Gradio的IP地址+端口来访问。 | |
产品说明: | |
1. 采用大模型的核心功能 + 专属定制化功能的方式,来实现一个专属的大语言模型解决方案。 | |
2. 在专属定制化功能中包含了报告模块、商业分析模块、培训资料模块。配置了专属的prompt,以及对应的模型参数。【话术:定制化的大模型接口 + 结构化的提示词工程 + 业务流】 | |
3. 此版本可以支持多轮对话【注:目前强行限制在3轮以内】,但是会收到大模型基座的影响,目前是ChatGLM3-6B中的4096个token的限制。 | |
Theme默认设置为Dark: | |
1. css = """ | |
#mybutton {background-color: #CEFAFE; color: #06B6D4;} | |
#textarea {-webkit-text-fill-color:black; -webkit-opacity: 1;} | |
.message {font: 16px Arial, sans-serif, 'ui-sans-serif', Montserrat, 'system-ui';} | |
""" | |
2. with gr.Blocks(theme=gr.themes.Base(primary_hue='sky', text_size='md'), css=css, title="大语言模型专项模块", js=js_func) as demo: | |
''' | |
##TODO 1. 将LLM改成公网Qwen API版本。 | |
import gradio as gr | |
import requests | |
import os | |
from rich import print | |
import os | |
import sys | |
import time | |
import pandas as pd | |
import numpy as np | |
import sys | |
import time | |
import PyPDF2 | |
from PyPDF2 import PdfReader | |
import docx ## 需要安装python-docx,否则会报错。 | |
from typing import Any | |
import requests | |
import csv | |
import os | |
from rich import print | |
import pandas | |
import io | |
from io import StringIO | |
from transformers import AutoModel, AutoTokenizer | |
import mdtex2html | |
import dashscope | |
from dotenv import load_dotenv | |
from http import HTTPStatus | |
from dashscope import Generation | |
load_dotenv() | |
### 设置openai的API key | |
dashscope.api_key = os.environ['dashscope_api_key'] | |
### Gradio设置为默认Dark | |
js_func = """ | |
function refresh() { | |
const url = new URL(window.location); | |
if (url.searchParams.get('__theme') !== 'dark') { | |
url.searchParams.set('__theme', 'dark'); | |
window.location.href = url.href; | |
} | |
} | |
""" | |
# ''' Start: Environment settings. ''' | |
# os.environ['SENTENCE_TRANSFORMERS_HOME'] = '/Users/yunshi/Downloads/chatGLM/My_LocalKB_Project/' | |
# os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1" | |
# # import PyPDF4 | |
# # from PyPDF4 import PdfFileReader | |
# import torch | |
# mps_device = torch.device("mps") ## 在mac机器上需要加上这句。 | |
### 在langchain中定义chatGLM作为LLM。 | |
from typing import Any, List, Mapping, Optional | |
from langchain.callbacks.manager import CallbackManagerForLLMRun | |
from langchain.llms.base import LLM | |
from transformers import AutoTokenizer, AutoModel | |
# llm_filepath = str("/Users/yunshi/Downloads/chatGLM/ChatGLM3-6B/6B") ## 第三代chatGLM 6B W/ code-interpreter | |
## 在ChatGLM3-6B中成功部署。 | |
# class chatGLM(): | |
# def __init__(self, model_name) -> None: | |
# self.tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True) | |
# # self.model = AutoModel.from_pretrained(model_name, trust_remote_code=True).half().cuda().eval() ##PC CUDA机器上用。 | |
# self.model = AutoModel.from_pretrained(model_name, trust_remote_code=True).half().to('mps') ##Mac机器上用。 | |
# def __call__(self, prompt) -> Any: | |
# # response, _ = self.model.chat(self.tokenizer , prompt) # 这里演示未使用流式接口. stream_chat() | |
# response, _ = self.model.stream_chat(self.tokenizer, prompt) # 尝试用stream_chat() | |
# return response | |
# chatglm = chatGLM(model_name=llm_filepath) | |
''' End: Environment settings. ''' | |
# ''' Start: 以下加载本地知识的核心内容。''' | |
# from langchain.document_loaders import UnstructuredFileLoader | |
# from langchain.text_splitter import CharacterTextSplitter | |
# # from langchain.embeddings.openai import OpenAIEmbeddings | |
# from langchain.embeddings.huggingface import HuggingFaceEmbeddings | |
# from langchain.vectorstores import FAISS | |
# ## 加载文件 | |
# filepath = "/Users/yunshi/Downloads/txt_dir/Sparks_of_AGI.pdf" | |
# # filepath = "/Users/yunshi/Downloads/txt_dir/浙江省院前急救质控统计指标.pdf" | |
# loader = UnstructuredFileLoader(filepath) | |
# docs = loader.load() | |
# ## 文本分割 | |
# # text_splitter = CharacterTextSplitter(chunk_size=5000, chunk_overlap=200) | |
# docs = CharacterTextSplitter(chunk_size=5000, chunk_overlap=200).split_documents(docs) | |
# ## 创建向量数据库 | |
# # embeddings = OpenAIEmbeddings(disallowed_special=()) | |
# embedding_model_name = 'GanymedeNil/text2vec-large-chinese' | |
# # embeddings = HuggingFaceEmbeddings(model_name=embedding_model_name) ## 这里是联网情况下连接huggingface后使用。 | |
# embeddings = HuggingFaceEmbeddings(model_name='/Users/yunshi/Downloads/chatGLM/My_LocalKB_Project/GanymedeNil_text2vec-large-chinese/') ## 这里会有个“No sentence-transformers model found with name“的warning,但不是error,不影响使用。 | |
# ### 比较的中文embeddding之一。 | |
# # from text2vec import SentenceModel | |
# # embeddings = SentenceModel('shibing624/text2vec-base-chinese-sentence', device=mps_device) | |
# # embeddings = HuggingFaceEmbeddings() | |
# vector_store = FAISS.from_documents(docs, embeddings) | |
# '''End: 至此本地加载知识库过程完成。''' | |
# ### 读取教材资料,docx文档 | |
# doc = docx.Document("./sample.docx") | |
# mytext = "" | |
# for paragraph in doc.paragraphs: | |
# mytext += paragraph.text | |
# ### 在工作台展示一部分内容 | |
# showtext = "" | |
# for paragraph in doc.paragraphs[:12]: | |
# showtext += paragraph.text | |
# print(showtext) | |
## 一键生成培训资料的环境设定 | |
# training_content = mytext.replace("['", "").replace("']", "") | |
# generate_message = gr.Textbox(f"""你是一个专业的培训材料制作者。我需要你根据提供的内容生成培训材料,内容如下:{training_content}""", visible=False) #! 注意这里的type,不能是简单的str。 | |
# system_prompt_message = """你是一个专业的培训材料制作者。我需要你根据提供的内容生成培训材料,内容如下:""" | |
# system_prompt = [{"role": "system", "content": f"""{system_prompt_message} {training_content}"""}] | |
# print('system_prompt:', system_prompt) | |
# prompt_templates = {"Default ChatGPT": ""} | |
### set an empty state in Gradio. | |
def get_empty_state(): | |
return {"total_tokens": 0, "messages": []} | |
## 重新生成对话,regenerate功能的核心,主要是将最后一次chatbot的回答清空。 | |
# def reload(chatbot): | |
def regenerate(chatbot): | |
chatbot[-1][1] = "" #! 清空最后一次的回答。 | |
return chatbot | |
## system prompt for LLM | |
system_prompt = [{"role": "system", "content": '你是一个专业和友好的AI助手。除非被要求,否则你默认的回答语言是中文。'}] | |
### 手动添加prompt templates。 | |
# prompt_templates = { | |
# '默认角色': "你是一个专业的人工智能助手。", | |
# '周报写作': "使用下面提供的文本作为中文周报的基础,生成一个简洁的摘要,突出最重要的内容。该报告应以 markdown 格式编写,并应易于阅读和理解,以满足一般受众的需要。特别是要注重提供对利益相关者和决策者有用的见解和分析。你也可以根据需要使用任何额外的信息或来源。", | |
# '写作建议': "我希望你能充当一名人工智能写作导师。我将为你提供一个需要帮助提高写作水平的学生,你的任务是使用人工智能工具,如自然语言处理,给学生反馈如何提高他们的写作水平。你还应该利用你的修辞学知识和关于有效写作技巧的经验,以建议该学生如何以书面形式更好地表达他们的思想和观点。我的第一个要求是 [修改文本]", | |
# } | |
### 导入收集到的有用prompts。 | |
raw_prompts = pd.read_excel("./raw_prompts.xlsx", usecols=['category','prompt'], index_col='category') | |
prompt_templates = raw_prompts.to_dict()['prompt'] | |
def on_prompt_template_change(prompt_template): | |
if not isinstance(prompt_template, str): return | |
# print(prompt_template) | |
return prompt_templates[prompt_template] | |
chat_hist = [] | |
def submit_message(radio, chatbot_history, temperature, max_tokens,top_p,presence_penalty): ## working. | |
# input_prompt = chatbot_history ## 单轮对话 working。 | |
input_prompt = chatbot_history ## working。支持多轮对话。 | |
print("input_prompt", input_prompt) | |
###NOTE: 保留3次历史记录,原生ChatGPT的上下文也只能到这里了。 | |
### 只把三次历史记录放入prompt中,这样可以保留三轮对话的历史。 | |
prompt = [] | |
if len(input_prompt) > 3: | |
for x in input_prompt[-3:]: | |
prompt.append(x) | |
else: | |
prompt = input_prompt | |
prompt = [item for sublist in prompt for item in sublist if item is not None] | |
prompt = '。'.join(prompt) | |
print('prompt now is:', prompt) | |
print('start the default version of Qwen') | |
## Role的范式。 | |
# prompt_msg = {"role": "user", "content": prompt} | |
# system_prompt = [{"role": "system", "content": '你是一个专业和友好的AI助手。'}] | |
try: | |
## no stream version. | |
# completion_1 = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=system_prompt + [prompt_msg], temperature=0.7, max_tokens=1024) | |
# history.append(prompt_msg) | |
# history.append(completion_1.choices[0].message.to_dict()) | |
# print('completion_1:',completion_1.choices[0].message.content) | |
# # state['total_tokens'] += completion_1['usage']['total_tokens'] | |
# messages = system_prompt + [prompt_msg] | |
# input_prompt[-1][1] = "" | |
# openai_client = OpenAI() | |
# for resp in openai_client.chat.completions.create(model=model_choice, messages=messages, stream=True, temperature=temperature, max_tokens=max_tokens,top_p=top_p,presence_penalty=presence_penalty): | |
# answer = str(resp.choices[0].delta.content) | |
# if answer != "None": | |
# ##NOTE: 这里是单论聊天的版本。 | |
# # resp_history.append(answer) #* working! | |
# # result = "".join(resp_history).strip() #* working! | |
# # yield [[prompt, result]] #* 记得这个格式。这只能单论聊天。 | |
# ##* 多轮聊天的版本。 | |
# input_prompt[-1][1] += answer | |
# yield input_prompt | |
##* 多轮会话,带有历史记忆。因为history参数的原因? | |
# for response, history in chatglm.model.stream_chat(chatglm.tokenizer, query=input_prompt[-1][0], history=history): ## 一轮对话。working. | |
# for response, history in chatglm.model.stream_chat(chatglm.tokenizer, query=str(input_prompt)): ## 这里保留了所有的chat history在input_prompt中。 | |
# for response, history in chatglm.model.stream_chat(chatglm.tokenizer, query=str(input_prompt[-1][0])): ## 从用langchain的自定义方式来做。 | |
# for response, history in chatglm.model.stream_chat(chatglm.tokenizer, query=prompt): ## 这里保留了所有的chat history在input_prompt中。 | |
# for response, history in chatglm.model.stream_chat(chatglm.tokenizer, query=prompt): ### Working. original code here. 这里保留了所有的chat history在input_prompt中。 | |
input_prompt[-1][1] = "" | |
messages = [ | |
{'role': 'user', 'content': prompt}] | |
responses = Generation.call(model="qwen-turbo", | |
messages=messages, | |
result_format='message', # 设置输出为'message'格式 | |
stream=True, # 设置输出方式为流式输出 | |
incremental_output=True # 增量式流式输出 | |
) | |
for response in responses: | |
if response.status_code == HTTPStatus.OK and len(response.output.choices[0]['message']['content']) > 0: | |
# if response != "<br>": | |
# print('response of model:', response) | |
# input_prompt[-1][1] = response ## working. ChatGLM的输出。 | |
# response.output.choices[0]['message']['content'] ### 标准的Qwen输出格式。 | |
# input_prompt[-1][1] = response.output.choices[0]['message']['content'] ## working. | |
input_prompt[-1][1] += response.output.choices[0]['message']['content'] ## working. | |
yield input_prompt | |
except Exception as e: | |
print(e) | |
error = str(e) | |
# messages = [{"role": "system", "content": "你是一个专业和友好的AI助手。"},] | |
# messages.append({"role": "user", "content": ""}) | |
# input_prompt[-1][1] += error | |
input_prompt[-1][1] = error | |
yield input_prompt ## 将错误打印到output的textbox里面。 | |
# print(input_prompt) | |
return input_prompt | |
## 插入chatbot的user问题。 原始代码参考: https://www.gradio.app/guides/creating-a-custom-chatbot-with-blocks | |
def user(user_message, chat_history): | |
# print('chat_history:', chat_history) | |
# return "", chat_history + [[user_message, None]] ## possiblly orginal code? | |
return "", chat_history + [[user_message, None]] | |
## 报告模块的内容合并。Gradio不接受直接的str相加,所以要通过函数来实现,并且在button click中实现。 | |
def report_prompt(system_prompt, report_method, user_prompt, report_requirement): | |
total_prompt = system_prompt + "\n\n" + "你撰写报告时采用的分析方法是:" + report_method + "\n\n 以下是报告的基础信息:\n" + user_prompt + "\n\n 其他报告写作的要求如下:\n\n" + report_requirement | |
return total_prompt | |
## 数据分析模块的内容合并。Gradio不接受直接的str相加,所以要通过函数来实现,并且在button click中实现。 | |
def data_prompt(system_prompt, method_prompt, user_prompt, report_requirement): | |
total_prompt = system_prompt + "\n" + user_prompt.to_markdown() + "\n\n" +"分析方法采用:"+ method_prompt + "\n\n"+ report_requirement | |
return total_prompt | |
### 培训模块的内容合并。Gradio不接受直接的str相加,所以要通过函数来实现,并且在button click中实现。 | |
def train_combine_prompt(train_doc, user_prompt, train_requirement): | |
total_prompt = train_doc + "\n\n" + user_prompt + "\n\n" + train_requirement | |
return total_prompt | |
def clear_conversation(): | |
return gr.update(value=None, visible=True), None, "", get_empty_state() | |
# return "", "", [] | |
css = """ | |
#mybutton {background-color: #CEFAFE; color: #06B6D4;} | |
#textarea {-webkit-text-fill-color:black; -webkit-opacity: 1;} | |
.message {font: 16px Arial, sans-serif, 'ui-sans-serif', Montserrat, 'system-ui';} | |
""" | |
# css = None | |
with gr.Blocks(theme=gr.themes.Base(primary_hue='sky', text_size='md'), css=css, title="大语言模型专项模块", js=js_func) as demo: | |
# with gr.Blocks(theme=gr.themes.Monochrome(text_size='md'), css=css, title="培训资料专项大语言模型") as demo: | |
state = gr.State(get_empty_state()) | |
with gr.Row(): | |
# with gr.Column(elem_id="col-container",scale=1): | |
# # with gr.Tab('参考提示词'): | |
# prompt_template = gr.Dropdown(label="选择提示词类型:", value="教案策划",choices=list(prompt_templates.keys())) | |
# default_prompt_value = "我希望您充当教育内容创建者。您需要为教科书、在线课程和讲义等学习材料创建引人入胜且信息丰富的内容。我的第一个建议请求是“我需要帮助制定针对高中生的可再生能源课程计划。”" | |
# prompt_template_preview = gr.Textbox(label="提示词预设内容:", value=default_prompt_value, show_label=True, lines=5, show_copy_button=True) | |
with gr.Column(elem_id="col-container",scale=4): | |
gr.Markdown("""# **大语言模型企业智能化管理中心** """, elem_id="header") | |
gr.Markdown(""" 说明: 本大模型为企业专项定制。提供高度可控、可调节、可迭代的大语言模型工具箱。用户可以根据自己的需求,灵活配置工具箱的功能和参数。可以满足不同用户的个性化需求,让用户能够充分发挥大语言模型的潜力。例如,对于常规业务人员,可以选择使用功能简单、参数较少的工具箱,以便快速上手。对于经验丰富的用户来说,可以选择使用功能复杂、参数较多的工具箱,以便进行更深入的研究。适用于各种业务场景的开发和使用。""") | |
with gr.Row(): | |
with gr.Column(): | |
# gr.Markdown("""### 企业级大语言模型 """) | |
chatbot = gr.Chatbot(elem_id="message", height=600, label="大模型对话区", show_label=True, show_copy_button=True, layout='panel', likeable=True) ## style来设置对话框高度。 | |
# chatbot = gr.Chatbot(elem_id="message", height=600, label="中交建大模型对话区") ## style来设置对话框高度。 | |
# output_message = gr.Textbox(label='大语言模型的回答',lines=10).style(show_copy_button=True) ## textbox version。style来设置对话框高度。 | |
# radio = gr.Radio(['培训资料生成模式', '资料优化模型','配图生成模式'], value='培训资料生成模式',label="大语言模型运行模式") | |
## 根据要求选择不同的按键类型,button或者icon。 | |
with gr.Row(): | |
with gr.Column(min_width=837): | |
# with gr.Column(scale=8): | |
input_message = gr.Textbox(lines=1, label="输入您的要求", show_label=True, placeholder="在这里输入您的要求按Enter提交", visible=True, show_copy_button=True) | |
with gr.Row(): | |
# with gr.Column(min_width=15): | |
with gr.Column(scale=1): | |
# btn_clear_conversation = gr.Button("\u2716", variant="primary", visible=True).style(full_width=False, size="lg") | |
btn_clear_conversation = gr.Button("开启新对话", variant="secondary", visible=True, size='lg') | |
# with gr.Column(scale=1): | |
# # btn_stop = gr.Button("\u25FD", variant="primary", visible=True).style(full_width=False, size="lg") | |
# btn_stop = gr.Button("终止当前问题/任务", variant="secondary", visible=True, size='lg') | |
# with gr.Column(scale=1): | |
# # btn_stop = gr.Button("\u25FD", variant="primary", visible=True).style(full_width=False, size="lg") | |
# btn_generate = gr.Button("一键生成分析报告", variant="primary", visible=True, size='lg') | |
with gr.Column(min_width=100): | |
# with gr.Column(scale=1): | |
btn_regenerate = gr.Button("重新生成答案", variant="secondary", visible=True, size='lg') | |
# with gr.Column(scale=1): | |
# # btn_stop = gr.Button("\u25FD", variant="primary", visible=True).style(full_width=False, size="lg") | |
# btn_exam = gr.Button("一键生成培训考题", variant="primary", visible=True, size='lg') | |
with gr.Column(scale=1): | |
# btn_submit = gr.Button("\u2714", variant="primary", visible=True).style(full_width=False, size="lg") | |
btn_submit = gr.Button("提交您的要求", variant="primary", visible=True, size='lg') | |
with gr.Column(scale=2): ### 原先设置为2. | |
# gr.Markdown("## 工作区") | |
# with gr.Tab('专项业务板块'): | |
'''以下为报告撰写模块''' | |
with gr.Tab('报告撰写模块'): | |
# with gr.Accordion('报告撰写模块', open=True): | |
# report_input = gr.Textbox(lines=5, label="输入报告基础内容", show_label=True, placeholder="报告基础内容", visible=True, show_copy_button=True) | |
report_input = gr.Textbox(lines=5, label="输入基本信息", show_label=True, placeholder="中小企业加快数字化转型,龙头骨干企业更要发挥引领示范作用。走进位于两江新区的集团自动化的“黑灯工厂”,1000多台机器人高速运转,机械手臂有序协作。在这里,冲压完成一套汽车部件仅需5秒钟,2分钟便可下线一辆新车。", visible=True, show_copy_button=True) | |
# train_sys_prompt = gr.Textbox("你是一个专业的咨询顾问。你写作的风格专业且详实,使用的语言为中文。我需要你根据如下内容撰写一份报告:", label="报告要求设定",visible=True, interactive=True, show_copy_button=True) | |
report_sys_prompt = gr.Textbox("你是一个专业的咨询顾问。我需要你撰写报告,你的写作风格专业且尽可能的详细,除非特别说明否则你使用的语言为中文。", label="报告要求设定", visible=True, interactive=True, show_copy_button=True) | |
report_method = gr.Dropdown(choices=['扩写内容','润色文案','重写材料'], interactive=True, label="报告撰写方法", value="扩写内容", multiselect=False, show_label=True) | |
report_requirement = gr.Textbox("""标题:简明扼要地概括汇报内容。 | |
正文:分为[基本情况]、[主要做法]、[下一步计划]三个部分。 | |
结尾:总结全文,提出希望。 | |
""", label="报告格式设定",show_label=True, show_copy_button=True,visible=True, interactive=True) | |
# train_text = gr.Textbox(lines=3, label='输出内容风格', show_label=True, show_copy_button=True, value=report_requirement) | |
btn_report = gr.Button("一键生成汇报材料", variant="primary", visible=True, size='lg') | |
'''以下为简易分析模块''' | |
with gr.Tab('商业分析模块'): | |
# with gr.Accordion('报告撰写模块', open=True): | |
biz_analysis_input = gr.Textbox(lines=5, label="输入基本信息", show_label=True, placeholder="9月份我部门共成单19件(注:8月份为21件);收到既有客户投诉246起(注:8月份为199起);潜在客户咨询152起(注:与8月份124起)", visible=True, show_copy_button=True) | |
# train_sys_prompt = gr.Textbox("你是一个专业的咨询顾问。你写作的风格专业且详实,使用的语言为中文。我需要你根据如下内容撰写一份报告:", label="报告要求设定",visible=True, interactive=True, show_copy_button=True) | |
biz_analysis_sys_prompt = gr.Textbox(lines=3, value="你是一个专业的商业分析顾问。我需要你撰写商业分析材料,你的写作风格专业且尽可能的详细,除非特别说明否则你使用的语言为中文。", label="报告要求设定", visible=True, interactive=True, show_copy_button=True) | |
biz_analysis_method = gr.Dropdown(choices=['头脑风暴', '整体分析','趋势判断','SMART分析','SWOT分析','精益分析','5W1H分析','PEST分析','金字塔原理','六顶思考帽'], interactive=True, label="商业分析方法", value="头脑风暴", multiselect=False, show_label=True) | |
biz_analysis_requirement = gr.Textbox(lines=4, value="""1. 将数据整理成Markdown表格的形式。 | |
2. 必须有标题。 | |
3. 使用一、二、三格式的序号。 | |
4. 最后有总结。 | |
""", label="报告格式设定",show_label=True, show_copy_button=True,visible=True, interactive=True) | |
# train_text = gr.Textbox(lines=3, label='输出内容风格', show_label=True, show_copy_button=True, value=biz_analysis_requirement) | |
btn_biz_analysis = gr.Button("一键生成分析报告", variant="primary", visible=True, size='lg') | |
###NOTE: 以下模块为数据分析模块,国产模型不稳定,暂时不开放! | |
# with gr.Tab('高级分析模块'): | |
# ## 上传功能 | |
# with gr.Row(): | |
# # file_output = gr.UploadButton(label='上传数据文件区', file_count="single", file_types=[".csv"]) | |
# file_output = gr.File(label='上传数据文件区', file_count="single", file_types=[".csv"]) | |
# ##NOTE: convert the uploaded file into dataframe, so that the Gradio can process it. | |
# def csv_file(file_output): | |
# res = pd.read_csv(file_output) | |
# return res | |
# with gr.Row(): | |
# md_table = gr.DataFrame() | |
# file_output.upload(fn=csv_file, inputs=file_output, outputs=md_table, queue=False) #! Gradio中需要通过函数来获得结果,否则都是Gradio内部定义的数据结构,如File,无法被直接访问或使用。 | |
# # with gr.Row(): | |
# # gr.DataFrame("/Users/yunshi/Downloads/360Data/Data Center/Working-On Task/演讲与培训/2023ChatGPT/Coding/code_interpreter/rawdata/iris.csv") | |
# data_sys_prompt = gr.Textbox("""你是一个专业的数据科学家。你需要保持专业的风格且分析内容详实,使用的语言为中文,回复时使用markdown格式。我需要你对如下数据中的[X, Y]进行分析并给出计算结果:\n\n""", lines=3, label="分析要求设定",visible=True, interactive=True, show_copy_button=True) | |
# data_method = gr.Dropdown(choices=['数据整体描述','描述性统计:汇总值、平均值、标准差、分位数', '相关性分析', '分类汇总'], label="数据分析方法", value="描述性统计:平均值、汇总值、标准差、中位数、极数", multiselect=False, interactive=True,show_label=True) | |
# # data_input = gr.Textbox(lines=5, label="输入数据内容", show_label=True, placeholder="数据基础内容", visible=True, show_copy_button=True, interactive=True) | |
# data_requirement = gr.Textbox("""目标:发现数据中的问题和关键点。 | |
# 分析方法:解释上述分析方法的基本原理。 | |
# 分析结论:提出结论,揭示潜在可能原因和对应的措施。 | |
# """, lines=5, label="分析输出设定",show_label=True, show_copy_button=True,visible=True, interactive=True) | |
# # data_analysis_requirement = gr.Textbox(lines=3, label='输出内容风格', show_label=True, show_copy_button=True, value=data_requirement) | |
# btn_data = gr.Button("一键生成数据分析", variant="primary", visible=True, size='lg') | |
with gr.Tab('培训资料模块'): | |
# with gr.Accordion('培训资料模块', open=False): | |
with gr.Row(): | |
# file_output = gr.UploadButton(label='上传数据文件区', file_count="single", file_types=[".csv"]) | |
uploaded_training_file = gr.File(label='上传培训资料区(注:文档内容限制在3000个汉字以内)', file_count="single", file_types=[".docx"]) | |
##NOTE: convert the uploaded file into dataframe, so that the Gradio can process it. | |
def convert_file(upload_file): | |
# res = pd.read_csv(file_output) ## read csv file. | |
### 读取教材资料,docx文档 | |
doc = docx.Document(upload_file) | |
my_text = "" | |
for paragraph in doc.paragraphs: | |
if not paragraph.text.isspace(): ## 判断是否有空行。 | |
my_text += paragraph.text | |
### 在工作台展示一部分内容 | |
show_text = "" | |
for paragraph in doc.paragraphs[:5]: | |
if not paragraph.text.isspace(): ## 判断是否有空行。 | |
show_text += paragraph.text | |
# print(show_text) | |
return my_text, show_text | |
# my_text, show_text = convert_file(uploaded_training_file) ## 单独运行一次这个函数,为了后面直接拼接字符串用。 | |
with gr.Row(): | |
my_doc = gr.TextArea(visible=False) | |
show_doc = gr.TextArea(label="培训资料展示与确认",visible=True, lines=5) | |
uploaded_training_file.upload(fn=convert_file, inputs=uploaded_training_file, outputs=[my_doc, show_doc],queue=False) #! Gradio中需要通过函数来获得结果,否则都是Gradio内部定义的数据结构,如File,无法被直接访问或使用。 | |
## 一键生成培训资料的环境设定 | |
# training_content = show_doc.replace("['", "").replace("']", "") | |
# system_prompt_message = """你是一个专业的培训材料制作者。我需要你根据提供的内容生成培训材料,内容如下:""" | |
train_prompt = gr.Textbox(value=("""你是一个专业的培训材料制作者。我需要你根据提供的内容生成培训材料,内容如下:"""), visible=False) #! 注意这里的type,不能是简单的str。 | |
# system_prompt = [{"role": "system", "content": f"""{system_prompt_message} {training_content}"""}] ### userful only in OpenAI API. | |
# train_requirement_text = """标题:[培训主题] | |
# 培训目标:[培训目标] | |
# 模块内容:涵盖目标和关键领域的详细内容 | |
# 培训方式:引人入胜的活动,以强化所讨论的概念 | |
# 评估方法:评估学习者理解和知识保留的方法。 | |
# """ | |
# train_requirement = gr.Textbox(lines=5, label='报告风格', show_label=True, show_copy_button=True, value=train_requirement_text) | |
train_requirement = gr.Textbox(lines=5, label='培训材料风格', show_label=True, show_copy_button=True, value="""标题:[培训主题] | |
培训目标:[培训目标] | |
模块内容:涵盖目标和关键领域的详细内容 | |
培训方式:引人入胜的活动,以强化所讨论的概念 | |
评估方法:评估学习者理解和知识保留的方法。 | |
""") | |
total_prompt = gr.TextArea(visible=False) | |
# uploaded_training_file.change(train_combine_prompt, [train_prompt, my_doc, train_requirement], total_prompt) | |
# total_prompt = (f"""你是一个专业的培训材料制作者。我需要你根据提供的内容生成培训材料,内容如下: \n {my_text}""") + "\n 培训内容设计需要参考如下要求:" + train_requirement | |
btn_training = gr.Button("一键生成培训资料", variant="primary", visible=True, size='lg') | |
traing_exam_prompt = gr.Textbox(lines=2, value="""你是一个专业的培训材料制作者。我需要你根据上述内容,设计3道单选题和2道问答题。你需要给出题目内容和对应的参考答案。""", label="培训考题要求", show_copy_button=True, visible=True) #! 注意这里的type,不能是简单的str。 | |
btn_training_exam = gr.Button("一键生成培训考试题目", variant="primary", visible=True, size='lg') | |
with gr.Tab(label='高级设置', elem_id='tab'): | |
with gr.Accordion('模型设置', open=True): | |
radio = gr.Radio(['核心模式', '优化模式','其他模式'], value='核心模式', label="大语言模型运行模式") | |
claim_value = str("大语言具有多种高级设置选项来调整其模型。1. Temperature:温度调整文本的多样性。温度值越高,生成的文本越随机。2. Token:控制生成文本的长度。3. 'top_p':0.0到1.0 (默认 1.0) ,类似Temperature,也叫核采样。4.presence_penalty:惩罚原始文本中已经出现过的单词/短语,从而鼓励生成无重复的输出。" | |
) | |
claim = gr.Textbox(value=claim_value, label="大模型参数简介",type="text", show_label=True, lines=5) | |
temperature = gr.Slider(minimum=0, maximum=2.0, value=0.7, step=0.1, label="Temperature参数",info="数值越高语句越灵活") | |
max_tokens = gr.Slider(minimum=100, maximum=14096, value=3000, step=100, | |
label="单次聊天最多Token数", info="平均1.12个token约等于1个汉字") | |
top_p = gr.Slider(minimum=0, maximum=1, value=1, step=0.1, label="top_p参数",info="数值越低语句越固定") | |
presence_penalty = gr.Slider(minimum=0, maximum=1, value=0.5, step=0.1, label="penalty参数",info="0没有惩罚,1完全禁止输出复制的单词") | |
# with gr.Tab('参考提示词'): | |
with gr.Accordion('参考提示词', open=True): | |
prompt_template = gr.Dropdown(label="选择提示词类型:", value="教案策划",choices=list(prompt_templates.keys())) | |
default_prompt_value = "我希望您充当教育内容创建者。您需要为教科书、在线课程和讲义等学习材料创建引人入胜且信息丰富的内容。我的第一个建议请求是“我需要帮助制定针对高中生的可再生能源课程计划。”" | |
prompt_template_preview = gr.Textbox(label="提示词预设内容:", value=default_prompt_value, show_label=True, lines=5, show_copy_button=True) | |
### 上传功能模块 | |
# with gr.Tab('上传文件'): | |
# with gr.Row(): | |
# file_output = gr.File(label='上传文件区', file_count="single", file_types=[".pdf", ".docx",".csv"]) | |
# with gr.Column(scale=1): | |
# btn_process = gr.Button('解析文件', variant="primary", visible=True, size='lg') | |
## click + submit. 注意,这里的input_message必须是类似gr.Textbox这样的模块type。普通的str不行。 | |
btn_submit_event = btn_submit.click(user, [input_message, chatbot], [input_message, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) | |
input_message.submit(user, [input_message, chatbot], [input_message, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) | |
btn_clear_conversation.click(clear_conversation, [], [input_message, chatbot]) | |
### 报告撰写专项模块按键 | |
total_prompt = gr.Textbox(visible=False) ## 用于汇总所有的prompt,然后输入chatbot。 | |
btn_report.click(report_prompt, [report_sys_prompt, report_method, report_input, report_requirement], [total_prompt], queue=True).then(user, [total_prompt, chatbot], [total_prompt, chatbot], queue=True).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) | |
### 商业分析撰写专项模块按键 | |
total_prompt = gr.Textbox(visible=False) ## 用于汇总所有的prompt,然后输入chatbot。 | |
btn_biz_analysis.click(report_prompt, [biz_analysis_sys_prompt, biz_analysis_method, biz_analysis_input, biz_analysis_requirement], [total_prompt], queue=False).then(user, [total_prompt, chatbot], [total_prompt, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) | |
# ### 数据分析专项模块按键 | |
##TODO 尝试用ChatGLM3中的code-interpreter来完成。 | |
# # report_prompt = gr.Textbox(value=f"你是一个专业的咨询顾问。你写作的风格专业且详实,使用的语言为中文。我需要你根据如下内容撰写一份报告:", visible=False) | |
# # train_sys_prompt = gr.Textbox("你是一个专业的咨询顾问。你写作的风格专业且详实,使用的语言为中文。我需要你根据如下内容撰写一份报告:") | |
# total_prompt = gr.Textbox(visible=False) ## 用于汇总所有的prompt,然后输入chatbot。 | |
# # btn_report.click(user, [report_prompt, chatbot], [report_prompt, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) | |
# # btn_data.click(data_prompt, [data_sys_prompt, data_method, file_output, data_requirement], [total_prompt], queue=False).then(user, [total_prompt, chatbot], [total_prompt, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) ## 可以看见这个file_output的完整链接。 | |
# btn_data.click(data_prompt, [data_sys_prompt, data_method, md_table, data_requirement], [total_prompt], queue=False).then(user, [total_prompt, chatbot], [total_prompt, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) ##TODO:尝试把数据导入。 | |
### 培训资料专项模块按键 | |
btn_training.click(train_combine_prompt, [train_prompt, my_doc, train_requirement], [total_prompt], queue=False).then(user, [total_prompt, chatbot], [total_prompt, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) | |
## 把total_prompt作为中间变量。否则,textbox中的内容用user()函数提交后会被清空。 | |
def exam_prompt(traing_exam_prompt): | |
total_prompt = traing_exam_prompt | |
return total_prompt | |
btn_training_exam.click(exam_prompt, traing_exam_prompt, total_prompt).then(user, [total_prompt, chatbot], [total_prompt, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) | |
# null_message = gr.Textbox(value=None, visible=False) | |
# btn_regenerate.click(user, [null_message, chatbot], [null_message, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) ## working. | |
# exam_prompt = gr.Textbox("你根据上述的内容,生成3道单选题和2道简答题。风格专业且简洁。", visible=False) | |
# btn_exam.click(user, [exam_prompt, chatbot], [exam_prompt, chatbot], queue=False).then(submit_message, [radio, chatbot,temperature,max_tokens,top_p,presence_penalty], chatbot) ## working. | |
## regenerate button。重新提交对话。 | |
btn_regenerate.click(regenerate, chatbot, chatbot).then(submit_message, [ | |
radio, chatbot, temperature, max_tokens, top_p, presence_penalty], chatbot) | |
## stop button中止提交程序运行。 | |
# btn_stop.click(fn=None, inputs=None, outputs=None, cancels=[btn_submit_event]) | |
prompt_template.change(on_prompt_template_change, inputs=[prompt_template], outputs=[prompt_template_preview]) | |
demo.load() | |
auth_list = ( | |
('1234', '1234'), | |
('joeshi', 'joeshi'), | |
('guojing', 'guojing'), | |
('chengrui', 'chengrui'), | |
('lbh', 'lbh'), | |
('zhangqian888', 'zhangqian888'), | |
('scottl', 'scottl'), | |
('test001', 'test001'), | |
('test002', 'test002'), | |
('test003', 'test003'), | |
) | |
### 用户名和密码认证 | |
# user_csv = pd.read_csv('auth_list_enterprise.csv') | |
# auth_list = [(x, y) for (x, y) in user_csv[['username', 'password']].values] | |
# demo.launch(height='1200px') | |
# demo.launch(height='1200px', auth=auth_list, auth_message="欢迎使用企业大语言模型培训专属模块", share=True) | |
# demo.launch(height='1500px', auth=auth_list, auth_message="欢迎使用中交建财务共享中心企业大语言模型平台", share=False).queue() | |
# demo.launch(height='1500px', server_name="0.0.0.0", server_port=7860, share=False).queue() | |
demo.launch(height='1500px', server_name="0.0.0.0", server_port=7860, auth=auth_list, auth_message="欢迎使用企业大语言模型平台", share=False).queue() |