搭建自己的GPT

server/2024/9/24 8:23:45/

搭建自己的GPT

    • 文章说明
    • 核心代码
    • 效果展示
    • 源码下载

文章说明

目前GPT的使用比较主流,现有开源大模型,可以拉取到本地进行部署,搭建属于自己的GPT对话工具;主要用于熟悉大模型的本地搭建;本文采用开源的Ollama进行服务提供,官网已提供控制台版本的提问方式,也有采用docker部署Web ui的功能;我选择本地自己搭建一个简单的对话ui,进行简单使用;该模型部署在本机消耗的资源较大,且模型的回答能力不如千问、文心一言等;

采用md-editor-v3,将返回的内容进行markdown格式展示,效果感觉还不错

同时采用indexDB存储对话记录,部署起来也非常便捷

Ollama大模型下载在官网下载即可

核心代码

App.vue代码

<script setup>javascript">
import {nextTick, onBeforeMount, reactive, watch} from "vue";
import {dbOperation} from "@/DbOperation";
import "@/config.js"
import {openDb} from "@/config";
import {confirm, message} from "@/util";
import {MdPreview} from 'md-editor-v3';
import 'md-editor-v3/lib/preview.css';const data = reactive({content: "",messageList: [],
});let isReplying = false;
let container;function getMaxHeight() {container = document.getElementsByClassName("container")[0];container.scrollTo({top: container.scrollHeight,behavior: "smooth"});
}onBeforeMount(() => {openDb(() => {dbOperation.getAllData((res) => {data.messageList = res.data;nextTick(() => {getMaxHeight();});});});
});watch(() => data.content, () => {if (data.content.length > 500) {data.content = String(data.content).slice(0, 500);}
});const avatarRobot = require("@/image/1.jpg");
const avatarUser = require("@/image/2.jpg");function question() {if (isReplying) {message("正在对话中", "warning");return;}isReplying = true;const messageItem = {question: data.content,reply: "",createTime: new Date(),};data.messageList.push(messageItem);setTimeout(() => {const height = container.scrollHeight;container.scrollTo({top: height,behavior: "smooth"});}, 0);fetch(new Request('http://localhost:11434/api/chat', {method: 'post',mode: "cors",body: JSON.stringify({"model": "llama3.1","messages": [{"role": "user","content": data.content}],}),})).then(response => {data.content = "";const reader = response.body.getReader();read();function read() {reader.read().then(({done, value}) => {if (done) {isReplying = false;dbOperation.add(messageItem, () => {message("对话成功", "success");});return;}const readContent = new Uint8Array(value);const content = JSON.parse(Uint8ArrayToString(readContent)).message.content;data.messageList[data.messageList.length - 1].reply += content;read();}).catch(error => {message(error, "error");});}}).catch(error => {message(error, "error");});
}function Uint8ArrayToString(fileData) {const decoder = new TextDecoder('utf-8');return decoder.decode(fileData);
}function editQuestion(item) {data.content = item.question;
}function copy(item) {navigator.clipboard.writeText(item.reply).then(() => {message("复制到剪切板", "success");});
}function deleteItem(item) {confirm("确认要删除该消息吗?", () => {data.messageList = data.messageList.filter(message => message.id !== item.id);dbOperation.delete(item.id, () => {message("删除成功", "success");});});
}
</script><template><div class="container"><div class="message-container"><div v-for="item in data.messageList" :key="item.id" class="message-item"><div class="create-time">{{ item.createTime }}</div><div class="user"><img :src="avatarUser" alt=""/><p><MdPreview v-model="item.question"/></p><i class="iconfont icon-edit" @click="editQuestion(item)"></i></div><div class="robot"><img :src="avatarRobot" alt=""/><p><MdPreview v-model="item.reply"/></p><i class="iconfont icon-copy" @click="copy(item)"></i><i class="iconfont icon-delete" @click="deleteItem(item)"></i></div></div></div><div class="input-container"><textarea v-model="data.content"/><p class="tip">{{ data.content.length }}/500</p><i class="iconfont icon-send" @click="question"></i></div></div>
</template><style lang="scss">
* {padding: 0;margin: 0;box-sizing: border-box;
}.container {min-width: 20rem;width: 100vw;height: 100vh;background-color: #eaedf6;overflow: auto;position: relative;user-select: none;.message-container {max-width: 70rem;width: 100%;height: fit-content;min-height: calc(100vh - 8rem);position: absolute;top: 0;left: 50%;transform: translateX(-50%);padding: 0 1rem 8rem;overflow: auto;.message-item {margin: 1.5rem 0;.create-time {height: 1rem;line-height: 1rem;font-size: 0.6rem;color: #999;margin-bottom: -0.5rem;margin-left: 0.5rem;}.user, .robot {margin: 1rem 0;display: flex;position: relative;&:hover .icon-edit, &:hover .icon-copy, &:hover .icon-delete {display: block;}img {border-radius: 50%;width: 2.5rem;height: 2.5rem;}p {flex: 1;display: flex;align-items: center;margin-left: 0.5rem;.md-editor-preview-wrapper {padding: 0 1rem;}}.icon-edit {position: absolute;right: 0.5rem;bottom: 0;transform: translateY(-50%);display: none;}.icon-copy {position: absolute;right: 1.8rem;bottom: 0;transform: translateY(-50%);display: none;}.icon-delete {position: absolute;right: 0.5rem;bottom: 0;transform: translateY(-50%);display: none;}}}}.input-container {max-width: 70rem;width: 80%;height: 6rem;position: fixed;bottom: 1rem;left: 50%;transform: translateX(-50%);background-color: #fff;border-radius: 1rem;&:focus-within {box-shadow: 0 0 1rem 0.1rem #888888;}textarea {outline: none;border: none;padding: 0.6rem;font-size: 1.2rem;resize: none;width: 100%;height: 100%;position: absolute;left: 0;top: 0;border-radius: 1rem;}.tip {font-size: 0.6rem;position: absolute;right: 1rem;bottom: 0.5rem;}.icon-send {font-size: 1.5rem;position: absolute;right: 1rem;bottom: 2rem;cursor: pointer;}}
}
</style>

效果展示

安装启动Ollama
在这里插入图片描述

问答演示1
在这里插入图片描述

问答演示2
在这里插入图片描述

问答演示3
在这里插入图片描述

源码下载

搭建自己的GPT


http://www.ppmy.cn/server/105794.html

相关文章

【Material-UI】深入了解Radio Group中的useRadioGroup Hook

文章目录 一、什么是useRadioGroup&#xff1f;1.1 Hook的返回值 二、useRadioGroup的基本用法2.1 代码示例2.2 代码解析 三、useRadioGroup的应用场景3.1 动态样式调整3.2 高级交互逻辑 四、使用useRadioGroup的最佳实践4.1 保持代码简洁4.2 结合主题定制4.3 注意无障碍设计 五…

Java—Arrays api

public static String toString(数组) //把数组拼接成一个字符串 public static int binarySearch(数组&#xff0c;查找的元素) //二分查找法查找元素 public static int[] copyOf(原数组,新数组长度) //拷贝数组 public st…

《黑神话.悟空》:一场跨越神话与现实的深度探索

"近期我偶然邂逅了一个极为出色的人工智能学习平台&#xff0c;它不仅内容深入浅出&#xff0c;讲解方式还风趣幽默&#xff0c;让人学习起来既轻松又高效。如此宝藏资源&#xff0c;我迫不及待想要与各位共享。即刻点击让我们一起进入这个精彩纷呈的学习网站吧&#xff0…

USB3.0硬件简单概述

关于USB2.0&#xff0c;小白在之前的文章简单的描述过。关于USB3.0&#xff0c;今天小白也简单的介绍下。 相比较于USB2.0&#xff0c;USB3.0有了很大的变化。信号端USB3.0除了包含USB2.0的四根信号&#xff0c;还新增了2对差分信号SSRXN SSRXP SSTXN SSTXP以及GND_DRAIN(信号…

Mysql基础操作-常见SQL语句

背景知识 SQL语句分类 数据定义语言 (Data Definition Language, DDL) 这类语句用于定义数据库结构&#xff0c;包括创建、修改和删除数据库对象如表、索引、视图等。 数据操纵语言 (Data Manipulation Language, DML) 这类语句用于添加、读取、更新和删除数据。 数据查询语言…

vue3+ts+Go使用百度地图路书实现历史轨迹回放、轨迹回放进度、聚合点、自定义弹框和实时监控视频、多路视频轮巡播放

前言 分享一个刚做完项目集成技术&#xff0c;一个车辆行驶轨迹监控、行车视频监控、对特种车辆安全监管平台&#xff0c;今年政府单位有很多监管平台项目&#xff0c;例如&#xff1a;渣土车监控、租出车监管、危害气体运输车监管等平台&#xff0c;这些平台都有车辆行驶轨迹…

python小游戏——躲避球(可当课设)

游戏简介&#xff1a; 没有美术&#xff0c;画面简洁&#xff08;懒得做&#xff09;。玩家控制小球躲避敌人&#xff08;上下左右&#xff0c;闪避&#xff09;&#xff0c;敌人体积越大速度越慢&#xff0c;随机生成道具球&#xff08;目前只有生命球&#xff09;&#xff0…

【单片机】LCD1602和OLED里,如何实现滚动显示特效?

如何在OLED显示16个字符的同时实现滚动特效 1. 基本思路 滚动特效的核心思路是在一个固定长度的显示区域内,通过不断改变显示内容的起始位置,模拟出内容在屏幕上滚动的效果。我们可以使用一个定时器来周期性地更新显示内容,从而实现动态滚动。 2. 代码分析 以下是实现滚…