• 如何快速搭建一个大模型?简单的UI实现


    8d1e21ef06c141ba8b452891f2f9e583.png

    🔥博客主页:是dream

    🚀系列专栏:深度学习环境搭建环境配置问题解决自然语言处理语音信号处理项目开发

    💘每日语录:相信自己,一路风景一路歌,人生之美,正在于此。

    🎉感谢大家点赞👍收藏⭐指正✍️

    0469b341a8fc44abb317ade91d055c88.png

    前言:本文章纯属是自己无聊,调用了星火认知大模型的接口,并封装成一个脚本。但测试感觉星火认知大模型也不算太智能,但奈何人家提供了免费的token,当然,也可以根据自己的需要,去调用国内的一些大模型。

    目录

    一、申请免费的token

    二、设置UI界面        

    三、运行效果

    四、封装成exe文件        


    一、申请免费的token

            这里我使用的是星火认知大模型,前往官网:星火认知大模型

            网上有很多的教程,这里不再赘述。

            申请后,你需要保存的有三个

            ① appid

            ② api_secret        

            ③ api_key

    二、设置UI界面        

            需要用到wxpython:GUI图形库,网上有很多安装wxpython的教程,这里不再赘述。

            wxpython依赖的whl文件(网上下载很慢,cp36对应python3.6):下载地址

    52cdc5d6643d4a7988ec68215cd7eca4.png

            这里我直接把UI界面的代码附上。

            需要更改① appid ②api_secret  ③ api_key

    1. import tkinter as tk
    2. from tkinter import scrolledtext, filedialog, messagebox
    3. import SparkApi
    4. class ChatApp:
    5. def __init__(self, master):
    6. self.master = master
    7. master.title("是dream-星火大模型UI界面")
    8. self.dialog_text = scrolledtext.ScrolledText(
    9. self.master, wrap=tk.WORD, width=50, height=20, font=("Microsoft YaHei UI", 12)
    10. )
    11. self.dialog_text.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
    12. self.dialog_text.grid_propagate(False) # 阻止自动调整大小
    13. self.label_input = tk.Label(self.master, text="请您在下方输入:", font=("Microsoft YaHei UI", 12))
    14. self.label_input.grid(row=1, column=0, padx=3, pady=3, sticky="w")
    15. input_frame = tk.Frame(master)
    16. input_frame.grid(row=2, column=0, pady=10, sticky="nsew")
    17. input_frame.grid_columnconfigure(0, weight=3)
    18. self.input_entry = tk.Entry(
    19. input_frame, bd=2, relief=tk.GROOVE, font=("Microsoft YaHei UI", 12),
    20. borderwidth=4, highlightthickness=1, width=20
    21. )
    22. self.input_entry.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
    23. self.input_entry.grid_propagate(False) # 阻止自动调整大小
    24. self.input_entry.bind("", self.send_on_enter)
    25. button_frame = tk.Frame(master)
    26. button_frame.grid(row=3, column=0, pady=10, sticky="nsew")
    27. self.send_button = tk.Button(button_frame, text="发送", command=self.send_message,
    28. font=("Microsoft YaHei UI", 12))
    29. self.send_button.grid(row=0, column=0, padx=5, sticky="nsew")
    30. self.file_button = tk.Button(button_frame, text="选择文本", command=self.load_file,
    31. font=("Microsoft YaHei UI", 12))
    32. self.file_button.grid(row=0, column=1, padx=5, sticky="nsew")
    33. self.save_button = tk.Button(
    34. button_frame, text="保存对话内容", command=self.save_to_text, font=("Microsoft YaHei UI", 12)
    35. )
    36. self.save_button.grid(row=0, column=2, padx=5, sticky="nsew")
    37. button_frame.grid_columnconfigure(0, weight=1)
    38. button_frame.grid_columnconfigure(1, weight=1)
    39. button_frame.grid_columnconfigure(2, weight=1)
    40. master.grid_rowconfigure(0, weight=1)
    41. master.grid_rowconfigure(1, weight=0)
    42. master.grid_rowconfigure(3, weight=1)
    43. master.grid_columnconfigure(0, weight=1)
    44. initial_text = "提前告诉星火大模型的内容,让其更关注你问的方向。"
    45. # sparkAPI(initial_text) # 如果要提前送内容给模型,请取消注释
    46. self.dialog_text.insert(tk.END,
    47. "你好!作者:“是dream”!CSDN主页:https://blog.csdn.net/qq_63159704?spm=1000.2115.3001.5343\n\n")
    48. def send_on_enter(self, event):
    49. self.send_message()
    50. def send_message(self):
    51. user_input = self.input_entry.get()
    52. if user_input.strip():
    53. assistant_response = sparkAPI(user_input)
    54. self.dialog_text.insert(tk.END, f"你: {user_input}\n")
    55. self.dialog_text.insert(tk.END, f"星火: {assistant_response}\n")
    56. self.input_entry.delete(0, tk.END)
    57. self.dialog_text.see(tk.END)
    58. else:
    59. messagebox.showinfo("提示", "请输入消息!")
    60. def load_file(self):
    61. file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
    62. if file_path:
    63. with open(file_path, 'r', encoding='utf-8') as file:
    64. content = file.read()
    65. self.input_entry.insert(tk.END, content)
    66. def save_to_text(self):
    67. content = self.dialog_text.get("1.0", tk.END)
    68. file_path = filedialog.asksaveasfilename(
    69. defaultextension=".txt", filetypes=[("Text files", "*.txt"), ("All files", "*.*")]
    70. )
    71. if file_path:
    72. with open(file_path, 'w', encoding='utf-8') as file:
    73. file.write(content)
    74. messagebox.showinfo("保存成功", "对话内容已保存为文本文件!")
    75. def sparkAPI(input_text):
    76. text.clear()
    77. questions = checklen(getText("user", input_text))
    78. SparkApi.answer = ""
    79. SparkApi.main(appid, api_key, api_secret, Spark_url, domain, questions)
    80. assistant_answer = SparkApi.answer
    81. text.append({"role": "assistant", "content": assistant_answer})
    82. return assistant_answer
    83. def getText(role, content):
    84. jsoncon = {"role": role, "content": content}
    85. text.append(jsoncon)
    86. return text
    87. def getlength(text):
    88. length = 0
    89. for content in text:
    90. temp = content["content"]
    91. leng = len(temp)
    92. length += leng
    93. return length
    94. def checklen(text):
    95. while getlength(text) > 8000:
    96. del text[0]
    97. return text
    98. if __name__ == "__main__":
    99. appid = ""
    100. api_secret = ""
    101. api_key = ""
    102. domain = "generalv2"
    103. Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat"
    104. text = []
    105. root = tk.Tk()
    106. root.geometry("800x750")
    107. chat_app = ChatApp(root)
    108. root.mainloop()

            还需要在相同目录下创建一个 SparkApi.py文件,并将下面的代码复制进去。

    1. import _thread as thread
    2. import base64
    3. import datetime
    4. import hashlib
    5. import hmac
    6. import json
    7. from urllib.parse import urlparse
    8. import ssl
    9. from datetime import datetime
    10. from time import mktime
    11. from urllib.parse import urlencode
    12. from wsgiref.handlers import format_date_time
    13. import websocket # 使用websocket_client
    14. answer = ""
    15. class Ws_Param(object):
    16. # 初始化
    17. def __init__(self, APPID, APIKey, APISecret, Spark_url):
    18. self.APPID = APPID
    19. self.APIKey = APIKey
    20. self.APISecret = APISecret
    21. self.host = urlparse(Spark_url).netloc
    22. self.path = urlparse(Spark_url).path
    23. self.Spark_url = Spark_url
    24. # 生成url
    25. def create_url(self):
    26. # 生成RFC1123格式的时间戳
    27. now = datetime.now()
    28. date = format_date_time(mktime(now.timetuple()))
    29. # 拼接字符串
    30. signature_origin = "host: " + self.host + "\n"
    31. signature_origin += "date: " + date + "\n"
    32. signature_origin += "GET " + self.path + " HTTP/1.1"
    33. # 进行hmac-sha256进行加密
    34. signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
    35. digestmod=hashlib.sha256).digest()
    36. signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')
    37. authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'
    38. authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
    39. # 将请求的鉴权参数组合为字典
    40. v = {
    41. "authorization": authorization,
    42. "date": date,
    43. "host": self.host
    44. }
    45. # 拼接鉴权参数,生成url
    46. url = self.Spark_url + '?' + urlencode(v)
    47. # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
    48. return url
    49. # 收到websocket错误的处理
    50. def on_error(ws, error):
    51. print("### error:", error)
    52. # 收到websocket关闭的处理
    53. def on_close(ws, one, two):
    54. print(" ")
    55. # 收到websocket连接建立的处理
    56. def on_open(ws):
    57. thread.start_new_thread(run, (ws,))
    58. def run(ws, *args):
    59. data = json.dumps(gen_params(appid=ws.appid, domain=ws.domain, question=ws.question))
    60. ws.send(data)
    61. # 收到websocket消息的处理
    62. def on_message(ws, message):
    63. # print(message)
    64. data = json.loads(message)
    65. code = data['header']['code']
    66. if code != 0:
    67. print(f'请求错误: {code}, {data}')
    68. ws.close()
    69. else:
    70. choices = data["payload"]["choices"]
    71. status = choices["status"]
    72. content = choices["text"][0]["content"]
    73. print(content, end="")
    74. global answer
    75. answer += content
    76. # print(1)
    77. if status == 2:
    78. ws.close()
    79. def gen_params(appid, domain, question):
    80. """
    81. 通过appid和用户的提问来生成请参数
    82. """
    83. data = {
    84. "header": {
    85. "app_id": appid,
    86. "uid": "1234"
    87. },
    88. "parameter": {
    89. "chat": {
    90. "domain": domain,
    91. "temperature": 0.5,
    92. "max_tokens": 2048
    93. }
    94. },
    95. "payload": {
    96. "message": {
    97. "text": question
    98. }
    99. }
    100. }
    101. return data
    102. def main(appid, api_key, api_secret, Spark_url, domain, question):
    103. # print("星火:")
    104. wsParam = Ws_Param(appid, api_key, api_secret, Spark_url)
    105. websocket.enableTrace(False)
    106. wsUrl = wsParam.create_url()
    107. ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)
    108. ws.appid = appid
    109. ws.question = question
    110. ws.domain = domain
    111. ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

    注意:调用星火大模型用到的是 websocket == 0.57.0,如果websocket的错,请更改版本。

    三、运行效果

     效果如下:

    a2530b06005c4e77aede068712288c97.png

    四、封装成exe文件        

            这里用到的是pyinstaller进行封装,运行以下代码进行安装:

    pip install pyinstaller

            运行下代码进行封装:

    pyinstaller -F -w GUI.py
    在`GUI.py`相同目录下会新增`dist`文件夹,内部放有`GUI.exe`文件。 GUI.py就是UI界面的代码,封装前,请保证代码能够正常运行。
    

    这样,你就可以将这个exe文件发送给你的好盆友,无需配置环境就可以对话。

    101b64fb7f674c74950c4c0f09eb8023.png

     de69c1431a9248258d3b7ff04a9d26a2.png

     🚀🚀🚀感谢关注我的CSDN博客,更多小技巧,请持续关注!

  • 相关阅读:
    开发知识点-人工智能-深度学习Tensorflow2.0
    前端开发常用哪些工具软件?
    机器学习中的各种损失函数(L1,L2,smoothL1,交叉熵 )
    BN踩坑记--谈一下Batch Normalization的优缺点和适用场景
    让充电器秒供多个快充口,乐得瑞推出1拖2功率分配快充线方案
    Java项目:校园宿舍管理系统(java+Springboot+Vue+maven+redis+Mysql)
    [附源码]java毕业设计个人信息管理系统
    软件测试 接口测试 Jmeter 5.5 安装教程
    3k+星星的eat_pytorch_in_20_days更新啦
    Linux 下指定端口开放访问权限
  • 原文地址:https://blog.csdn.net/qq_63159704/article/details/134627368