前言
大语言模型是指具有大规模参数和训练数据的语言模型。这些模型通常由深度学习算法训练而成,能够理解和生成人类语言,包括文本的理解、生成、翻译、摘要等任务。大语言模型在自然语言处理领域有着广泛的应用,可以用于智能对话系统、智能客服、文本生成、机器翻译、信息检索等方面。
近年来,随着深度学习技术的发展和计算资源的增加,大型语言模型的规模不断扩大,如GPT(生成式预训练模型)系列、BERT(双向编码器表示转换器)等。这些模型在训练时使用了大量的文本数据,并拥有数十亿或数百亿的参数量,从而能够更好地理解和生成复杂的语言表达。
大语言模型的出现和发展,为自然语言处理技术的进步提供了强大的驱动力,也为各种应用场景带来了更加智能和人性化的解决方案。然而,大语言模型也面临着一些挑战,如参数过大导致的计算资源消耗、模型的可解释性和偏差等问题,这些都是当前研究和应用中需要解决的课题。
核心代码
javascript
<template>
<div style="display: flex;flex-direction: column;align-items: center;width: 100%;height: 100%;background-color: #ccc;">
<div style="width: 70%;height: 100%;" class="home-container">
<el-row style="flex: 1;">
<el-col style="display: flex;flex-direction: column;" :span="6">
<h3>参数设置</h3>
<div>
<p title="插件自由度">插件自由度</p>
<el-slider style="width: 200px;" :min="1" :max="5" :show-tooltip="notShow" v-model="maxItem" />
</div>
<div style="display: flex;flex-direction: row;align-items: center;">
<p style="margin-right: 50px;" title="开启流式输出">流式输出</p>
<el-switch v-model="stream" />
</div>
<div>
<p>ins</p>
<el-select placeholder="none" v-model="ins">
<el-option v-for="item in inses" :key="item.label" :label="item.label" :value="item.value">{{ item.label
}}</el-option>
</el-select>
</div>
</el-col>
<el-col style="display: flex;flex-direction: column;" :span="18">
<div style="display: flex;flex-direction: row;align-items: center;">
<img class="home-logo" src="../../assets/img/th.jpg" alt="">
<div style="display: flex;flex-direction: column;">
<h3 style="text-align: left;">伟健小灵通</h3>
<p style="margin: 0;color: #9e9e9e;">伟健小灵通给你提供在线答疑</p>
</div>
</div>
<!-- chat -->
<div class="home-chat-container">
<div class="home-chat">
<div class="home-chat-user">
<div ref="scorllContainer" @scroll="handleScorll" style="overflow-y: scroll;">
<div v-for="item in messagesInfo" :key="item.timestep">
<div v-show="item.user"
style="display: flex;flex-direction: row; justify-content: flex-end;width: 100%;">
<div>
<div class="message-text">{{ item.text }}</div>
<div class="message-user">
<p style="color: #656873;margin-right: 10px;">{{ nick_name }}</p>
<p style="margin-right: 10px;">{{ item.time }}</p>
<img class="user-avatar" src="../../assets/img/emoji/clown-face.png" alt="">
</div>
</div>
</div>
<div v-show="!item.user"
style="display: flex;flex-direction: row;justify-content: flex-start;width: 100%;">
<div class="message-box">
<div class="message-backend-text" id="bufferString">{{ item.text }}
</div>
<div class="message-user">
<img style="margin-right: 10px;" class="user-avatar" src="../../assets/img/emoji/clown-face.png"
alt="">
<p style="margin-right: 10px;">{{ name }}</p>
<p style="color: #656873;margin-left: 10px;">{{ item.time }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="send-box">
<el-input :rows="1" :disabled="isDisabled" ref="sendIpt" style="flex: 1;font-size: 20px;"
@keydown.enter="keyDown" v-model="chatIpt" type="textarea"></el-input>
<div @click="handleSendMessage" class="send-btn">
<img style="width: 70%;height: 70%;" src="../../assets/img/emoji/rocket.png" alt="">
</div>
</div>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup>
// import { ref } from 'vue'
import { reqSendMessage } from '@/api/user'
import useUserStore from '@/store/modules/user'
import { getNowTime } from '../../utils/util'
const userStore = useUserStore()
import { ref, reactive, computed, nextTick, watch, VueElement, watchEffect } from 'vue'
const ins = ref('')
const inses = reactive([{ label: 'bm25', value: 'bm25' }, { label: 'embedding', value: 'embedding' }, { label: 'none', value: 'null' }, { label: 'embedding3', value: 'embedding3' }])
const maxItem = ref(0)
const stream = ref(true)
const chatIpt = ref('')
const notShow = ref(false)
const messagesInfo = ref([])
const homeChatUser = ref()
const isDisabled = ref(false)
const name = localStorage.getItem("name")
const id = localStorage.getItem("ID")
const nick_name = localStorage.getItem("NickName")
// let transfer = ref('')
let allMessages = reactive([])
const sendIpt = ref()
// const option = reactive({})
const scorllContainer = ref()
const sendMessageParams = reactive({
user_id: localStorage.getItem("ID"),
messages: []
})
// stream: stream.value,
// ins: ins.value,
// max_items: Math.ceil(maxItem.value / 100 * 5),
// watch(scorllContainer, (val, newVal) => {
// if (val.offsetHeight) {
// val.scrollTop = val.scrollHeight - val.offsetHeight
// }
// })
const keyDown = () => {
handleSendMessage()
}
const handleSendMessage = async () => {
sendMessageParams.stream = stream.value
sendMessageParams.max_items = maxItem.value
sendMessageParams.ins = ins.value
isDisabled.value = true
if (chatIpt.value) {
let userQuestion = {}
userQuestion.text = chatIpt.value
userQuestion.timestep = Date.now()
userQuestion.user = true
userQuestion.time = getNowTime()
messagesInfo.value.push(userQuestion)
sendMessageParams.messages.push({
user: true,
sender_name: nick_name,
sender_type: 'USER',
text: userQuestion.text
})
sendMessageParams.stream = stream.value
if (sendMessageParams.ins === '') {
sendMessageParams.ins = 'null'
}
if (sendMessageParams.max_items === 0) {
sendMessageParams.max_items = 1
}
if (!sendMessageParams.stream) {
let res = await reqSendMessage(sendMessageParams)
if (res) {
let option = {}
option.text = res.reply
option.time = getNowTime()
messagesInfo.value.push(option)
sendMessageParams.messages.push({
sender_name: name,
sender_type: 'BOT',
text: option.text
})
}
nextTick(() => {
isDisabled.value = false
sendIpt.value.focus()
scorllContainer.value.scrollTop = scorllContainer.value.scrollHeight - scorllContainer.value.offsetHeight
})
} else {
const url = `/api/chatcompletion_pro/${id}`
async function getResponse(content) {
let data = JSON.stringify({ ...content });
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${userStore.token}`
},
body: data
})
const reader = await res.body.getReader()
const decoder = new TextDecoder()
const option = reactive({})
option.text = "";
isDisabled.value = true
let reg = true
let resData = "";
while (1) {
const { done, value } = await reader.read()
if (done) {
break
}
if (reg) {
option.time = getNowTime()
messagesInfo.value.push(option)
reg = false
}
const text = decoder.decode(value)
// console.log(text);
let jsonData;
try {
jsonData = JSON.parse(text.substring(5))
} catch (err) {
resData += text;
// console.log(resData, "--------------");
try {
jsonData = JSON.parse(resData.substring(5))
resData = "";
} catch (err) {
continue;
}
}
if (jsonData.choices) {
for (let i = 0; i < jsonData.choices.length; i++) {
let choise = jsonData.choices[i];
if (choise.finish_reason === 'stop') {
break;
}
if (choise.messages) {
for (let j = 0; j < choise.messages.length; j++) {
option.text = option.text + choise.messages[j].text
// watchEffect(() => {
// scorllContainer.value.scrollTop = scorllContainer.value.scrollHeight - scorllContainer.value.offsetHeight + 30
// })
}
}
}
}
else {
ElMessageBox.alert('系统错误', '错误', {
confirmButtonText: 'OK',
callback: (action) => {
ElMessage({
type: 'error',
message: `action: ${action}`,
})
},
})
break
}
scorllContainer.value.scrollTop = scorllContainer.value.scrollHeight - scorllContainer.value.offsetHeight
}
sendMessageParams.messages.push({
sender_name: name,
sender_type: 'BOT',
text: option.text
})
nextTick(() => {
sendIpt.value.focus()
})
isDisabled.value = false
}
getResponse(sendMessageParams)
// for (let i = 0; i < messagesInfo.value.length; i++) {
// if (!messagesInfo.value[i].user) {
// messagesInfo.value[i].sender_type = 'BOT',
// messagesInfo.value[i].sender_name = name
// } else {
// messagesInfo.value[i].sender_type = 'USER',
// messagesInfo.value[i].sender_name = nick_name
// }
// allMessages.push(messagesInfo.value[i])
// }
// sendMessageParams.messages = allMessages
// allMessages = []
// console.log(sendMessageParams, '接口入参');
}
}
chatIpt.value = ''
// scrollBottom()
// console.log(sendMessageParams);
}
// computed(() => {
// return questionArr
// })
// let write = (words, container) => {
// if (words.length > 0) {
// let span = document.createElement("span")
// let del = words.shift()
// span.innerHTML = del
// container.appendChild(span)
// }
// }
</script>
<style scoped lang="scss">
.home-container {
background-color: #272a37;
padding: 20px;
box-sizing: border-box;
color: #fff;
display: flex;
flex-direction: column;
// overflow-y: scroll;
position: relative;
:deep(.el-switch__core) {
width: 50px;
}
.user-avatar {
width: 30px;
height: 30px;
border-radius: 50%;
}
.message-user {
display: flex;
flex-direction: row;
text-align: right;
align-items: center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.home-chat-container {
// height: 100%;
flex: 1;
box-sizing: border-box;
padding: 10px;
// padding-right: 10px;
.home-chat {
height: 100%;
background-color: rgb(50, 54, 68);
border-radius: 40px;
// padding: 30px;
display: flex;
padding: 20px;
flex-direction: column;
.home-chat-user {
// overflow-y: hidden;
// height: 100%;
flex: 1 0 auto;
height: 0;
padding: 20px;
display: flex;
flex-direction: column;
// overflow-y: scroll;
.message-text {
padding: 15px;
max-width: 90%;
border-radius: 20px 20px 5px 20px;
background-color: #95ec69;
color: #000;
font-size: 14px;
word-break: break-all;
// display: flex;
}
.message-box {
display: flex;
flex-direction: column;
.message-backend-text {
padding: 15px;
max-width: 90%;
border-radius: 20px 20px 20px 5px;
background-color: #fff;
color: #000;
font-size: 14px;
word-break: break-all;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
}
}
.send-box {
width: 100%;
padding: 20px;
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
max-height: 150px;
// position: absolute;
right: 20px;
bottom: 40px;
height: 85px;
.send-btn {
width: 45px;
height: 45px;
background-color: #08f;
margin-left: 20px;
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
.home-logo {
width: 45px;
height: 45px;
border-radius: 50%;
border: 2px solid #fff;
margin-right: 20px;
}
h4,
h3 {
margin: 0;
color: #fff;
}
h3 {
text-align: center;
}
}
</style>