接入本地模型

This commit is contained in:
aixianling
2023-06-12 17:27:53 +08:00
parent 5cc0b732c4
commit 8eb0db8401
2 changed files with 80 additions and 4 deletions

View File

@@ -16,7 +16,7 @@
<el-button type="text" @click="getModelAccount">应用</el-button>
</el-row>
</el-form-item>
<el-row v-loading="loadingAccount" element-loading-background="#272A37">
<el-row v-loading="loadingAccount" element-loading-background="#272A37" v-if="!isLocal">
<el-form-item label="账号用户" class="fill">{{ account.username }}</el-form-item>
<el-form-item label="账户余额" class="fill">{{ [account.usage, account.total].join(" / ") }}</el-form-item>
<el-button type="text" @click="getModelAccount">刷新</el-button>
@@ -57,7 +57,8 @@ export default {
models: () => Object.values(models),
account: v => v.settings.account || {usage: 0, total: 0},
apiKey: v => v.settings.model.apiKey || "key无效或网络波动,请重新尝试",
isGPT: v => v.settings.model.name == "ChatGPT"
isGPT: v => v.settings.model.name == "ChatGPT",
isLocal: v => typeof v.settings.model?.getAccount != "function"
},
methods: {
initModel(model) {
@@ -66,7 +67,7 @@ export default {
if (ins.apiKey) {
clearInterval(timer)
this.settings.model = ins
this.getModelAccount()
!this.isLocal && this.getModelAccount()
}
}, 500)
},
@@ -83,8 +84,8 @@ export default {
<style lang="scss" scoped>
.settings {
min-width: 375px;
margin-left: 16px;
width: 300px;
:deep(.el-form) {
.el-form-item__label {
@@ -108,6 +109,7 @@ export default {
border: 1px solid transparent;
cursor: pointer;
user-select: none;
width: 100%;
&.active {
border-color: #409EFF;

View File

@@ -212,6 +212,80 @@ export class ChatGLM extends BaseModel {
}
}
/**
* 集成私有的Alpaca
*/
export class Alpaca extends BaseModel {
static base = "https://testai.cunwuyun.cn"
static avatar = "https://cdn.cunwuyun.cn/img/logo.svg"
static name = "Alpaca"
static id = "alpaca-7b-plus"
static desc = "llama所基于的中文权重本地模型"
constructor(params) {
const {avatar, name, desc, id} = Alpaca
super({avatar, name, desc, id, ...params})
this.setApiKey("alpaca-7b-plus")
}
async chat(history) {
const messages = history.map(e => ({role: e.role, content: e.msg}))
return await axios.post(Alpaca.base + "/v1/chat/completions", JSON.stringify({messages, model: this.id}), {
headers: {
Authorization: 'Bearer ' + this.apiKey, "Content-Type": "application/json", Accept: "application/json",
},
}).then(res => res.json()).then(data => data?.choices?.[0]?.message?.content || "key无效或网络波动,请重新尝试");
}
async chatStream(history) {
const messages = history.map(e => ({role: e.role, content: e.msg}))
return await axios.post(Alpaca.base + "/v1/chat/completions", JSON.stringify({
messages,
model: this.id,
stream: true
}), {
headers: {
Authorization: 'Bearer ' + this.apiKey, "Content-Type": "application/json", Accept: "application/json",
},
}).then(res => res?.body?.getReader());
}
streamOutput(reader, chat) {
return reader.read().then(({done, value}) => {
if (done) {
return;
}
if (!chat.reminder) {
chat.reminder = ""
}
let decode = new TextDecoder().decode(value)
decode = chat.reminder + decode
let decodedArray = decode.split("data: ");
let longstr = "";
decodedArray.forEach(decoded => {
decoded = decoded.trim();
try {
if (longstr != "") {
decoded = longstr + decoded;
longstr = "";
}
} catch (e) {
longstr = decoded;
decoded = "";
}
if (!!decoded && decoded !== "[DONE]") {
const choices = JSON.parse(decoded).choices
if (choices?.length > 0) {
const response = choices[0].delta.content || "";
chat.msg += response
}
}
})
return this.streamOutput(reader, chat)
})
}
}
/**
* 集成免费的New Bing搜索,TODO
*/