mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-18 17:51:24 +00:00
perf: init model (#4610)
* fix: model config undefined value * perf: init model
This commit is contained in:
@@ -20,5 +20,5 @@ weight: 793
|
|||||||
1. 文件上传分块大小限制,避免超出 MongoDB 限制。
|
1. 文件上传分块大小限制,避免超出 MongoDB 限制。
|
||||||
2. 使用记录仪表盘,无法获取指定成员的使用统计。
|
2. 使用记录仪表盘,无法获取指定成员的使用统计。
|
||||||
3. 仪表盘接口,因未考虑时区问题,统计异常。
|
3. 仪表盘接口,因未考虑时区问题,统计异常。
|
||||||
4. LLM 模型测试接口,无法测试未启用的 LLM。
|
4. LLM 模型测试接口,无法测试未启用的 LLM。同时修复,模型测试接口会把模型自定义请求地址去除问题。
|
||||||
|
|
||||||
|
@@ -4,6 +4,12 @@ import { LogLevelEnum } from './log/constant';
|
|||||||
import { connectionMongo } from '../mongo/index';
|
import { connectionMongo } from '../mongo/index';
|
||||||
import { getMongoLog } from './log/schema';
|
import { getMongoLog } from './log/schema';
|
||||||
|
|
||||||
|
export enum EventTypeEnum {
|
||||||
|
outLinkBot = '[Outlink bot]',
|
||||||
|
feishuBot = '[Feishu bot]',
|
||||||
|
wxOffiaccount = '[Offiaccount bot]'
|
||||||
|
}
|
||||||
|
|
||||||
const logMap = {
|
const logMap = {
|
||||||
[LogLevelEnum.debug]: {
|
[LogLevelEnum.debug]: {
|
||||||
levelLog: chalk.green('[Debug]')
|
levelLog: chalk.green('[Debug]')
|
||||||
|
@@ -45,11 +45,13 @@ export const getAxiosConfig = (props?: { userKey?: OpenaiAccountType }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const createChatCompletion = async ({
|
export const createChatCompletion = async ({
|
||||||
|
modelData,
|
||||||
body,
|
body,
|
||||||
userKey,
|
userKey,
|
||||||
timeout,
|
timeout,
|
||||||
options
|
options
|
||||||
}: {
|
}: {
|
||||||
|
modelData?: LLMModelItemType;
|
||||||
body: ChatCompletionCreateParamsNonStreaming | ChatCompletionCreateParamsStreaming;
|
body: ChatCompletionCreateParamsNonStreaming | ChatCompletionCreateParamsStreaming;
|
||||||
userKey?: OpenaiAccountType;
|
userKey?: OpenaiAccountType;
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
@@ -70,10 +72,11 @@ export const createChatCompletion = async ({
|
|||||||
> => {
|
> => {
|
||||||
try {
|
try {
|
||||||
// Rewrite model
|
// Rewrite model
|
||||||
const modelConstantsData = getLLMModel(body.model);
|
const modelConstantsData = modelData || getLLMModel(body.model);
|
||||||
if (!modelConstantsData) {
|
if (!modelConstantsData) {
|
||||||
return Promise.reject(`${body.model} not found`);
|
return Promise.reject(`${body.model} not found`);
|
||||||
}
|
}
|
||||||
|
body.model = modelConstantsData.model;
|
||||||
|
|
||||||
const formatTimeout = timeout ? timeout : body.stream ? 60000 : 600000;
|
const formatTimeout = timeout ? timeout : body.stream ? 60000 : 600000;
|
||||||
const ai = getAIApi({
|
const ai = getAIApi({
|
||||||
|
@@ -23,13 +23,7 @@ import {
|
|||||||
} from '../../../common/system/config/controller';
|
} from '../../../common/system/config/controller';
|
||||||
import { delay } from '@fastgpt/global/common/system/utils';
|
import { delay } from '@fastgpt/global/common/system/utils';
|
||||||
|
|
||||||
/*
|
const getModelConfigBaseUrl = () => {
|
||||||
TODO: 分优先级读取:
|
|
||||||
1. 有外部挂载目录,则读取外部的
|
|
||||||
2. 没有外部挂载目录,则读取本地的。然后试图拉取云端的进行覆盖。
|
|
||||||
*/
|
|
||||||
export const loadSystemModels = async (init = false) => {
|
|
||||||
const getProviderList = () => {
|
|
||||||
const currentFileUrl = new URL(import.meta.url);
|
const currentFileUrl = new URL(import.meta.url);
|
||||||
const filePath = decodeURIComponent(
|
const filePath = decodeURIComponent(
|
||||||
process.platform === 'win32'
|
process.platform === 'win32'
|
||||||
@@ -37,15 +31,21 @@ export const loadSystemModels = async (init = false) => {
|
|||||||
: currentFileUrl.pathname
|
: currentFileUrl.pathname
|
||||||
);
|
);
|
||||||
const modelsPath = path.join(path.dirname(filePath), 'provider');
|
const modelsPath = path.join(path.dirname(filePath), 'provider');
|
||||||
|
return modelsPath;
|
||||||
|
};
|
||||||
|
|
||||||
return fs.readdirSync(modelsPath) as string[];
|
/*
|
||||||
};
|
TODO: 分优先级读取:
|
||||||
|
1. 有外部挂载目录,则读取外部的
|
||||||
|
2. 没有外部挂载目录,则读取本地的。然后试图拉取云端的进行覆盖。
|
||||||
|
*/
|
||||||
|
export const loadSystemModels = async (init = false) => {
|
||||||
const pushModel = (model: SystemModelItemType) => {
|
const pushModel = (model: SystemModelItemType) => {
|
||||||
global.systemModelList.push(model);
|
global.systemModelList.push(model);
|
||||||
|
|
||||||
if (model.isActive) {
|
if (model.isActive) {
|
||||||
global.systemActiveModelList.push(model);
|
global.systemActiveModelList.push(model);
|
||||||
}
|
|
||||||
if (model.type === ModelTypeEnum.llm) {
|
if (model.type === ModelTypeEnum.llm) {
|
||||||
global.llmModelMap.set(model.model, model);
|
global.llmModelMap.set(model.model, model);
|
||||||
global.llmModelMap.set(model.name, model);
|
global.llmModelMap.set(model.name, model);
|
||||||
@@ -83,6 +83,7 @@ export const loadSystemModels = async (init = false) => {
|
|||||||
global.systemDefaultModel.rerank = model;
|
global.systemDefaultModel.rerank = model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!init && global.systemModelList) return;
|
if (!init && global.systemModelList) return;
|
||||||
@@ -99,9 +100,10 @@ export const loadSystemModels = async (init = false) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const dbModels = await MongoSystemModel.find({}).lean();
|
const dbModels = await MongoSystemModel.find({}).lean();
|
||||||
const providerList = getProviderList();
|
|
||||||
|
|
||||||
// System model
|
// Load system model from local
|
||||||
|
const modelsPath = getModelConfigBaseUrl();
|
||||||
|
const providerList = fs.readdirSync(modelsPath) as string[];
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
providerList.map(async (name) => {
|
providerList.map(async (name) => {
|
||||||
const fileContent = (await import(`./provider/${name}`))?.default as {
|
const fileContent = (await import(`./provider/${name}`))?.default as {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { cloneDeep } from 'lodash';
|
||||||
import { SystemModelItemType } from './type';
|
import { SystemModelItemType } from './type';
|
||||||
|
|
||||||
export const getDefaultLLMModel = () => global?.systemDefaultModel.llm!;
|
export const getDefaultLLMModel = () => global?.systemDefaultModel.llm!;
|
||||||
@@ -53,5 +54,5 @@ export const findAIModel = (model: string): SystemModelItemType | undefined => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
export const findModelFromAlldata = (model: string) => {
|
export const findModelFromAlldata = (model: string) => {
|
||||||
return global.systemModelList.find((item) => item.model === model);
|
return cloneDeep(global.systemModelList.find((item) => item.model === model));
|
||||||
};
|
};
|
||||||
|
@@ -26,9 +26,9 @@ const MyNumberInput = (props: Props) => {
|
|||||||
<NumberInput
|
<NumberInput
|
||||||
{...restProps}
|
{...restProps}
|
||||||
onBlur={(e) => {
|
onBlur={(e) => {
|
||||||
const numE = Number(e.target.value);
|
const numE = e.target.value === '' ? '' : Number(e.target.value);
|
||||||
if (onBlur) {
|
if (onBlur) {
|
||||||
if (isNaN(numE)) {
|
if (numE === '') {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
onBlur('');
|
onBlur('');
|
||||||
} else {
|
} else {
|
||||||
@@ -46,9 +46,9 @@ const MyNumberInput = (props: Props) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const numE = Number(e);
|
const numE = e === '' ? '' : Number(e);
|
||||||
if (onChange) {
|
if (onChange) {
|
||||||
if (isNaN(numE)) {
|
if (numE === '') {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
onChange('');
|
onChange('');
|
||||||
} else {
|
} else {
|
||||||
@@ -62,6 +62,7 @@ const MyNumberInput = (props: Props) => {
|
|||||||
value: numE
|
value: numE
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
register(name).onChange(event);
|
register(name).onChange(event);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
"log_status": "Status",
|
"log_status": "Status",
|
||||||
"mapping": "Model Mapping",
|
"mapping": "Model Mapping",
|
||||||
"mapping_tip": "A valid Json is required. \nThe model can be mapped when sending a request to the actual address. \nFor example:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\nWhen FastGPT requests the gpt-4o model, the gpt-4o-test model is sent to the actual address, instead of gpt-4o.",
|
"mapping_tip": "A valid Json is required. \nThe model can be mapped when sending a request to the actual address. \nFor example:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\nWhen FastGPT requests the gpt-4o model, the gpt-4o-test model is sent to the actual address, instead of gpt-4o.",
|
||||||
"maxToken_tip": "The model max_tokens parameter, if left blank, means that the model does not support it.",
|
"maxToken_tip": "Model max_tokens parameter",
|
||||||
"max_temperature_tip": "If the model temperature parameter is not filled in, it means that the model does not support the temperature parameter.",
|
"max_temperature_tip": "If the model temperature parameter is not filled in, it means that the model does not support the temperature parameter.",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
"model_name": "Model name",
|
"model_name": "Model name",
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
"log_status": "状态",
|
"log_status": "状态",
|
||||||
"mapping": "模型映射",
|
"mapping": "模型映射",
|
||||||
"mapping_tip": "需填写一个有效 Json。可在向实际地址发送请求时,对模型进行映射。例如:\n{\n \"gpt-4o\": \"gpt-4o-test\"\n}\n当 FastGPT 请求 gpt-4o 模型时,会向实际地址发送 gpt-4o-test 的模型,而不是 gpt-4o。",
|
"mapping_tip": "需填写一个有效 Json。可在向实际地址发送请求时,对模型进行映射。例如:\n{\n \"gpt-4o\": \"gpt-4o-test\"\n}\n当 FastGPT 请求 gpt-4o 模型时,会向实际地址发送 gpt-4o-test 的模型,而不是 gpt-4o。",
|
||||||
"maxToken_tip": "模型 max_tokens 参数,如果留空,则代表模型不支持该参数。",
|
"maxToken_tip": "模型 max_tokens 参数",
|
||||||
"max_temperature_tip": "模型 temperature 参数,不填则代表模型不支持 temperature 参数。",
|
"max_temperature_tip": "模型 temperature 参数,不填则代表模型不支持 temperature 参数。",
|
||||||
"model": "模型",
|
"model": "模型",
|
||||||
"model_name": "模型名",
|
"model_name": "模型名",
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
"log_status": "狀態",
|
"log_status": "狀態",
|
||||||
"mapping": "模型對映",
|
"mapping": "模型對映",
|
||||||
"mapping_tip": "需填寫一個有效 Json。\n可在向實際地址傳送請求時,對模型進行對映。\n例如:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\n當 FastGPT 請求 gpt-4o 模型時,會向實際地址傳送 gpt-4o-test 的模型,而不是 gpt-4o。",
|
"mapping_tip": "需填寫一個有效 Json。\n可在向實際地址傳送請求時,對模型進行對映。\n例如:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\n當 FastGPT 請求 gpt-4o 模型時,會向實際地址傳送 gpt-4o-test 的模型,而不是 gpt-4o。",
|
||||||
"maxToken_tip": "模型 max_tokens 參數,如果留空,則代表模型不支援該參數。",
|
"maxToken_tip": "模型 max_tokens 參數",
|
||||||
"max_temperature_tip": "模型 temperature 參數,不填則代表模型不支援 temperature 參數。",
|
"max_temperature_tip": "模型 temperature 參數,不填則代表模型不支援 temperature 參數。",
|
||||||
"model": "模型",
|
"model": "模型",
|
||||||
"model_name": "模型名",
|
"model_name": "模型名",
|
||||||
|
@@ -356,7 +356,12 @@ export const ModelEditModal = ({
|
|||||||
</Td>
|
</Td>
|
||||||
<Td textAlign={'right'}>
|
<Td textAlign={'right'}>
|
||||||
<Flex justifyContent={'flex-end'}>
|
<Flex justifyContent={'flex-end'}>
|
||||||
<MyNumberInput register={register} name="maxResponse" {...InputStyles} />
|
<MyNumberInput
|
||||||
|
min={2000}
|
||||||
|
register={register}
|
||||||
|
name="maxResponse"
|
||||||
|
{...InputStyles}
|
||||||
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
@@ -372,6 +377,7 @@ export const ModelEditModal = ({
|
|||||||
<MyNumberInput
|
<MyNumberInput
|
||||||
register={register}
|
register={register}
|
||||||
name="maxTemperature"
|
name="maxTemperature"
|
||||||
|
min={0}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
{...InputStyles}
|
{...InputStyles}
|
||||||
/>
|
/>
|
||||||
|
@@ -79,6 +79,7 @@ const testLLMModel = async (model: LLMModelItemType, headers: Record<string, str
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { response, isStreamResponse } = await createChatCompletion({
|
const { response, isStreamResponse } = await createChatCompletion({
|
||||||
|
modelData: model,
|
||||||
body: requestBody,
|
body: requestBody,
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
|
Reference in New Issue
Block a user