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

news2024/11/27 10:24:16

🔥博客主页:真的睡不醒

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

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

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

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

目录

一、申请免费的token

二、设置UI界面        

三、运行效果

四、封装成exe文件        


一、申请免费的token

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

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

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

        ① appid

        ② api_secret        

        ③ api_key

二、设置UI界面        

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

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

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

        注意:需要将123.png更换为你想要的图片路径。

        同时需要更改① appid ② api_secret  ③ api_key

import tkinter as tk
from tkinter import scrolledtext, filedialog, messagebox
import SparkApi

class ChatApp:
    def __init__(self, master):
        self.master = master
        master.title("是dream-星火大模型UI界面")

        self.dialog_text = scrolledtext.ScrolledText(
            self.master, wrap=tk.WORD, width=50, height=20, font=("Microsoft YaHei UI", 12)
        )
        self.dialog_text.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
        self.dialog_text.grid_propagate(False)  # 阻止自动调整大小

        self.label_input = tk.Label(self.master, text="请您在下方输入:", font=("Microsoft YaHei UI", 12))
        self.label_input.grid(row=1, column=0, padx=3, pady=3, sticky="w")

        input_frame = tk.Frame(master)
        input_frame.grid(row=2, column=0, pady=10, sticky="nsew")
        input_frame.grid_columnconfigure(0, weight=3)

        self.input_entry = tk.Entry(
            input_frame, bd=2, relief=tk.GROOVE, font=("Microsoft YaHei UI", 12),
            borderwidth=4, highlightthickness=1, width=20
        )
        self.input_entry.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
        self.input_entry.grid_propagate(False)  # 阻止自动调整大小
        self.input_entry.bind("<Return>", self.send_on_enter)

        button_frame = tk.Frame(master)
        button_frame.grid(row=3, column=0, pady=10, sticky="nsew")

        self.send_button = tk.Button(button_frame, text="发送", command=self.send_message,
                                     font=("Microsoft YaHei UI", 12))
        self.send_button.grid(row=0, column=0, padx=5, sticky="nsew")

        self.file_button = tk.Button(button_frame, text="选择文本", command=self.load_file,
                                     font=("Microsoft YaHei UI", 12))
        self.file_button.grid(row=0, column=1, padx=5, sticky="nsew")

        self.save_button = tk.Button(
            button_frame, text="保存对话内容", command=self.save_to_text, font=("Microsoft YaHei UI", 12)
        )
        self.save_button.grid(row=0, column=2, padx=5, sticky="nsew")

        button_frame.grid_columnconfigure(0, weight=1)
        button_frame.grid_columnconfigure(1, weight=1)
        button_frame.grid_columnconfigure(2, weight=1)

        master.grid_rowconfigure(0, weight=1)
        master.grid_rowconfigure(1, weight=0)
        master.grid_rowconfigure(3, weight=1)
        master.grid_columnconfigure(0, weight=1)

        initial_text = "提前告诉星火大模型的内容,让其更关注你问的方向。"
        # sparkAPI(initial_text)   # 如果要提前送内容给模型,请取消注释
        self.dialog_text.insert(tk.END,
                                "你好!作者:“是dream”!CSDN主页:https://blog.csdn.net/qq_63159704?spm=1000.2115.3001.5343\n\n")

    def send_on_enter(self, event):
        self.send_message()

    def send_message(self):
        user_input = self.input_entry.get()
        if user_input.strip():
            assistant_response = sparkAPI(user_input)
            self.dialog_text.insert(tk.END, f"你: {user_input}\n")
            self.dialog_text.insert(tk.END, f"星火: {assistant_response}\n")
            self.input_entry.delete(0, tk.END)
            self.dialog_text.see(tk.END)
        else:
            messagebox.showinfo("提示", "请输入消息!")

    def load_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
        if file_path:
            with open(file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                self.input_entry.insert(tk.END, content)

    def save_to_text(self):
        content = self.dialog_text.get("1.0", tk.END)
        file_path = filedialog.asksaveasfilename(
            defaultextension=".txt", filetypes=[("Text files", "*.txt"), ("All files", "*.*")]
        )
        if file_path:
            with open(file_path, 'w', encoding='utf-8') as file:
                file.write(content)
            messagebox.showinfo("保存成功", "对话内容已保存为文本文件!")


def sparkAPI(input_text):
    text.clear()
    questions = checklen(getText("user", input_text))
    SparkApi.answer = ""
    SparkApi.main(appid, api_key, api_secret, Spark_url, domain, questions)
    assistant_answer = SparkApi.answer
    text.append({"role": "assistant", "content": assistant_answer})
    return assistant_answer


def getText(role, content):
    jsoncon = {"role": role, "content": content}
    text.append(jsoncon)
    return text


def getlength(text):
    length = 0
    for content in text:
        temp = content["content"]
        leng = len(temp)
        length += leng
    return length


def checklen(text):
    while getlength(text) > 8000:
        del text[0]
    return text


if __name__ == "__main__":
    appid = ""
    api_secret = ""
    api_key = ""
    domain = "generalv2"
    Spark_url = "ws://spark-api.xf-yun.com/v2.1/chat"

    text = []

    root = tk.Tk()
    root.geometry("800x750")
    chat_app = ChatApp(root)
    root.mainloop()

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

import _thread as thread
import base64
import datetime
import hashlib
import hmac
import json
from urllib.parse import urlparse
import ssl
from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time

import websocket  # 使用websocket_client

answer = ""


class Ws_Param(object):
    # 初始化
    def __init__(self, APPID, APIKey, APISecret, Spark_url):
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.host = urlparse(Spark_url).netloc
        self.path = urlparse(Spark_url).path
        self.Spark_url = Spark_url

    # 生成url
    def create_url(self):
        # 生成RFC1123格式的时间戳
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))

        # 拼接字符串
        signature_origin = "host: " + self.host + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + self.path + " HTTP/1.1"

        # 进行hmac-sha256进行加密
        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                 digestmod=hashlib.sha256).digest()

        signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')

        authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'

        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')

        # 将请求的鉴权参数组合为字典
        v = {
            "authorization": authorization,
            "date": date,
            "host": self.host
        }
        # 拼接鉴权参数,生成url
        url = self.Spark_url + '?' + urlencode(v)
        # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
        return url


# 收到websocket错误的处理
def on_error(ws, error):
    print("### error:", error)


# 收到websocket关闭的处理
def on_close(ws, one, two):
    print(" ")


# 收到websocket连接建立的处理
def on_open(ws):
    thread.start_new_thread(run, (ws,))


def run(ws, *args):
    data = json.dumps(gen_params(appid=ws.appid, domain=ws.domain, question=ws.question))
    ws.send(data)


# 收到websocket消息的处理
def on_message(ws, message):
    # print(message)
    data = json.loads(message)
    code = data['header']['code']
    if code != 0:
        print(f'请求错误: {code}, {data}')
        ws.close()
    else:
        choices = data["payload"]["choices"]
        status = choices["status"]
        content = choices["text"][0]["content"]
        print(content, end="")
        global answer
        answer += content
        # print(1)
        if status == 2:
            ws.close()


def gen_params(appid, domain, question):
    """
    通过appid和用户的提问来生成请参数
    """
    data = {
        "header": {
            "app_id": appid,
            "uid": "1234"
        },
        "parameter": {
            "chat": {
                "domain": domain,
                "temperature": 0.5,
                "max_tokens": 2048
            }
        },
        "payload": {
            "message": {
                "text": question
            }
        }
    }
    return data


def main(appid, api_key, api_secret, Spark_url, domain, question):
    # print("星火:")
    wsParam = Ws_Param(appid, api_key, api_secret, Spark_url)
    websocket.enableTrace(False)
    wsUrl = wsParam.create_url()
    ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)
    ws.appid = appid
    ws.question = question
    ws.domain = domain
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

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

三、运行效果

 效果如下:

四、封装成exe文件        

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

pip install pyinstaller

        运行下代码进行封装:

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

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

 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1254736.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DataGrip 2023.2.3(IDE数据库开发)

DataGrip是一款数据库集成开发环境&#xff08;IDE&#xff09;&#xff0c;用于数据库管理和开发。 DataGrip提供了许多强大的功能&#xff0c;如SQL语句编辑、数据库连接管理、数据导入和导出、数据库比较和同步等等。它支持多种数据库&#xff0c;如MySQL、PostgreSQL、Ora…

Python教程:DataFrame数据中使用resample计算月线平均值

在pandas库中&#xff0c;DataFrame可以使用resample()方法来对时间序列数据进行重采样。重采样是将原始数据按照指定的频率进行重新组织&#xff0c;以便进行更细粒度的分析或转换。下面是一个示例&#xff0c;演示如何使用resample()方法&#xff1a; # Author : 小红牛 # 微…

陶陶摘苹果、跳跃游戏

1. 陶陶摘苹果 题目描述&#xff1a; 陶陶家的院子里有一棵苹果树&#xff0c;每到秋天树上就会结出 10 个苹果。苹果成熟的时候&#xff0c;陶陶就会跑去摘苹果。陶陶有个 30 厘米高的板凳&#xff0c;当她不能直接用手摘到苹果的时候&#xff0c;就会踩到板凳上再试试。 现在…

人力资源管理后台 === 登陆+主页鉴权

目录 1. 分析登录流程 2. Vuex中用户模块的实现 3.Vue-cli代理解决跨域 4.axios封装 5.环境区分 6. 登录联调 7.主页权限验证-鉴权 1. 分析登录流程 传统思路都是登录校验通过之后&#xff0c;直接调用接口&#xff0c;获取token之后&#xff0c;跳转到主页。 vue-elemen…

概念解析 | 玻尔兹曼机

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:玻尔兹曼机。 概念解析 | 玻尔兹曼机 引言 随着人工智能技术的飞速发展,玻尔兹曼机作为一种重要的生成模型,受到了广泛的关注。 背景介绍 玻尔兹曼机(Boltzmann Machine)是一…

vs2019中出现Debug Error的原因

一般出现这种错误表示你的某个变量没有正确赋值&#xff0c;或者说本身在你的C程序中加了assert断言&#xff0c;assert的作用是先计算表达式expression,如果其值为假&#xff0c;那么它会打印一条错误信息 #include<assert.h> void assert(int expression); 例子&…

【23-24 秋学期】NNDL 作业8 卷积 导数 反向传播

习题5-2 证明宽卷积具有交换性&#xff0c; 即公式(5.13)&#xff0e; 图像X和卷积核W的宽卷积定义如下&#xff1a; 要证明&#xff1a;当图像X和卷积核W有固定长度时,他们的宽卷积具有满足交换性&#xff0c;如下&#xff1a; 设二维图像为&#xff1a;&#xff0c;也就是…

【华为OD】B\C卷真题 100%通过:找城市 多叉树实现 python源码

【华为OD】B\C卷真题 100%通过:找城市 多叉树实现 python源码 目录 题目描述&#xff1a; 示例1 示例2 解题思路&#xff1a; 代码实现&#xff1a; 题目描述&#xff1a; 一张地图上有n个城市&#xff0c;城市和城市之间有且只有一条道路相连&#xff1a;要么直接相连&…

Android设计模式--桥接模式

闻正言&#xff0c;行正道&#xff0c;左右前后皆正人 一&#xff0c;定义 将抽象部分与实现部分分离&#xff0c;使它们都可以独立地进行变化 二&#xff0c;使用场景 从模式的定义中&#xff0c;我们大致可以了解到&#xff0c;这里的桥接的作用其实就是连接抽象部分与实现…

如何提高API性能

下图给出了提高API性能的5个常用技巧 分页 当结果很大时&#xff0c;这是一种常见的优化。结果会流回客户端以提高服务响应能力。 异步日志记录 同步日志记录每次调用都会处理磁盘&#xff0c;并且会降低系统速度。异步日志记录首先将日志发送到无锁缓冲区并立即返回。日志将…

肾合胶囊 | 冬不养肾春易病,若出现了这六大表现,小心是肾虚!

冬季作为一年中最寒冷的季节&#xff0c;自然万物皆静谧闭藏&#xff0c;而肾具有潜藏、封藏、闭藏精气的特点&#xff0c;是封藏之本&#xff0c;肾的脏腑特性与冬季相通应&#xff0c;所以在冬季更应该重视养肾。 而现在正值初冬&#xff0c;正是开始养肾的最佳时间。此时培…

2018年3月26日 Go生态洞察:Go包版本管理提案分析

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Java核心知识点整理大全16-笔记

Java核心知识点整理大全-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全2-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全3-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全4-笔记-CSDN博客 Java核心知识点整理大全5-笔记-CSDN博客 Java核心知识点整理大全6…

4/5G互操作 EPSFB讲解

今天我们来讲一下4/5G之间之间互操作&#xff0c;以及5G的EPSFB是基于什么实现的~ 目录 4/5G互操作 重选 切换 基于覆盖的切换 基于业务的切换 两个面试问题 想要加快4G切换5G的速度&#xff0c;调哪个参数怎么调高效&#xff1f; 想要减慢5G切换4G的速度调哪个参数怎…

STM32 F1 串口空闲中断 + DMA实现数据发送

DMA实现数据发送 文章目录 DMA实现数据发送前言一、DMA二、代码编写1.DMA2.USART3.main 前言 当你遇到通信数据量大的时候&#xff0c;可以使用 空闲中断 DMA 的方案来减轻 CPU 的压力。 或者 在进行stm32开发时&#xff0c;有时会遇到这种情况&#xff1a;需要在设备间进行数…

字符串原地旋转

记录一下做的练习题 字符串原地旋转&#xff1a;五 三 mat [[1,2,3],[3,4,5],[4,5,6]] tag0 total 0 for i in mat:total total i[tag]tag 1 print(total) 四 X [[12,7,3],[4,5,6],[7,8,9]] Y [[5,8,1],[6,7,3],[4,5,9]] res [[0,0,0],[0,0,0],[0,0,0]] for i in rang…

2024年天津天狮学院市场营销专业《管理学》考试大纲

2024年天津天狮学院专升本市场营销专业高职升本入学考试《管理学》考试大纲 一、考试性质 《管理学》专业课程考试是天津天狮学院市场营销专业高职升本入学考试的必考科 目之一&#xff0c;其性质是考核学生是否达到了升入本科继续学习的要求而进行的选拔性考试。《管理学》考…

STM32 默认时钟更改 +debug调试

STM32时钟 文章目录 STM32时钟前言一、修改系统时钟二、DEBUG 前言 为什么我们要改STM32的时钟呢&#xff0c;打个比方在做SPI驱动的时候&#xff0c;需要16M的时钟&#xff0c;但是stm32默认是72的分频分不出来&#xff0c;这个时候我们就要改系统时钟了&#xff0c;那么怎么…

人工智能基础_机器学习050_对比sigmoid函数和softmax函数的区别_两种分类器算法的区别---人工智能工作笔记0090

可以看到最上面是softmax的函数对吧,但是如果当k = 2 那么这个时候softmax的函数就可以退化为sigmoid函数,也就是 逻辑斯蒂回归了对吧 我们来看一下推导过程,可以看到上面是softmax的函数 可以看到k=2 表示,只有两个类别对吧,两个类别的分类不就是sigmoid函数嘛对吧,所以说 …

算法设计与分析(贪心法)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…