fix: api access info
This commit is contained in:
@@ -58,5 +58,7 @@ export default {
|
|||||||
'clusters.addworker.metaxNotes':
|
'clusters.addworker.metaxNotes':
|
||||||
'If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, please create a symbolic link pointing to the MetaX installed path: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Same as <span class="bold-text">/opt/maca</span> directory.',
|
'If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, please create a symbolic link pointing to the MetaX installed path: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Same as <span class="bold-text">/opt/maca</span> directory.',
|
||||||
'clusters.addworker.cambriconNotes':
|
'clusters.addworker.cambriconNotes':
|
||||||
'If the <span class="bold-text">/usr/local/neuware</span> directory does not exist, please create a symbolic link pointing to the Cambricon installed path: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.'
|
'If the <span class="bold-text">/usr/local/neuware</span> directory does not exist, please create a symbolic link pointing to the Cambricon installed path: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.',
|
||||||
|
'clusters.addworker.hygonNotes-02':
|
||||||
|
'If failed to detect devices, please try to remove <span class="bold-text">--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib</span>.'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ export default {
|
|||||||
'clusters.addworker.metaxNotes':
|
'clusters.addworker.metaxNotes':
|
||||||
'If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, please create a symbolic link pointing to the MetaX installed path: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Same as <span class="bold-text">/opt/maca</span> directory.',
|
'If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, please create a symbolic link pointing to the MetaX installed path: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Same as <span class="bold-text">/opt/maca</span> directory.',
|
||||||
'clusters.addworker.cambriconNotes':
|
'clusters.addworker.cambriconNotes':
|
||||||
'If the <span class="bold-text">/usr/local/neuware</span> directory does not exist, please create a symbolic link pointing to the Cambricon installed path: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.'
|
'If the <span class="bold-text">/usr/local/neuware</span> directory does not exist, please create a symbolic link pointing to the Cambricon installed path: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.',
|
||||||
|
'clusters.addworker.hygonNotes-02':
|
||||||
|
'If failed to detect devices, please try to remove <span class="bold-text">--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib</span>.'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -111,5 +113,5 @@ export default {
|
|||||||
// 47. 'clusters.addworker.corexNotes': 'If the <span class="bold-text">/lib/modules</span> directory does not exist, please create a symbolic link pointing to the Iluvatar installed path: <span class="bold-text">ln -s /path/to/corex /lib/modules</span>. Same as <span class
|
// 47. 'clusters.addworker.corexNotes': 'If the <span class="bold-text">/lib/modules</span> directory does not exist, please create a symbolic link pointing to the Iluvatar installed path: <span class="bold-text">ln -s /path/to/corex /lib/modules</span>. Same as <span class
|
||||||
// 48. 'clusters.addworker.metaxNotes': 'If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, please create a symbolic link pointing to the MetaX installed path: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Same as <span class="bold-text">/opt/maca</span> directory.',
|
// 48. 'clusters.addworker.metaxNotes': 'If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, please create a symbolic link pointing to the MetaX installed path: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Same as <span class="bold-text">/opt/maca</span> directory.',
|
||||||
// 49. 'clusters.addworker.cambriconNotes': 'If the <span class="bold-text">/usr/local/neuware</span> directory does not exist, please create a symbolic link pointing to the Cambricon installed path: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.'
|
// 49. 'clusters.addworker.cambriconNotes': 'If the <span class="bold-text">/usr/local/neuware</span> directory does not exist, please create a symbolic link pointing to the Cambricon installed path: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.'
|
||||||
|
// 50. 'clusters.addworker.hygonNotes-02': 'If failed to detect devices, please try to remove <span class="bold-text">--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib</span>.'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -58,9 +58,11 @@ export default {
|
|||||||
'clusters.addworker.metaxNotes':
|
'clusters.addworker.metaxNotes':
|
||||||
'Если директория <span class="bold-text">/opt/mxdriver</span> не существует, создайте символическую ссылку на путь установки MetaX: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Аналогично для директории <span class="bold-text">/opt/maca</span>.',
|
'Если директория <span class="bold-text">/opt/mxdriver</span> не существует, создайте символическую ссылку на путь установки MetaX: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Аналогично для директории <span class="bold-text">/opt/maca</span>.',
|
||||||
'clusters.addworker.cambriconNotes':
|
'clusters.addworker.cambriconNotes':
|
||||||
'Если директория <span class="bold-text">/usr/local/neuware</span> не существует, создайте символическую ссылку на путь установки Cambricon: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.'
|
'Если директория <span class="bold-text">/usr/local/neuware</span> не существует, создайте символическую ссылку на путь установки Cambricon: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.',
|
||||||
|
'clusters.addworker.hygonNotes-02':
|
||||||
|
'If failed to detect devices, please try to remove <span class="bold-text">--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib</span>.'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
|
// 1. 'clusters.addworker.hygonNotes-02': 'If failed to detect devices, please try to remove <span class="bold-text">--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib</span>.'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -56,5 +56,7 @@ export default {
|
|||||||
'clusters.addworker.metaxNotes':
|
'clusters.addworker.metaxNotes':
|
||||||
'如果 <span class="bold-text">/opt/mxdriver</span> 目录不存在,请创建指向 MetaX 安装路径的符号链接:<span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>。与 <span class="bold-text">/opt/maca</span> 目录相同。',
|
'如果 <span class="bold-text">/opt/mxdriver</span> 目录不存在,请创建指向 MetaX 安装路径的符号链接:<span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>。与 <span class="bold-text">/opt/maca</span> 目录相同。',
|
||||||
'clusters.addworker.cambriconNotes':
|
'clusters.addworker.cambriconNotes':
|
||||||
'如果 <span class="bold-text">/usr/local/neuware</span> 目录不存在,请创建指向 Cambricon 安装路径的符号链接:<span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>。'
|
'如果 <span class="bold-text">/usr/local/neuware</span> 目录不存在,请创建指向 Cambricon 安装路径的符号链接:<span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>。',
|
||||||
|
'clusters.addworker.hygonNotes-02':
|
||||||
|
'如果未能检测到设备,请尝试移除 <span class="bold-text">--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib</span>。'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,16 +3,48 @@ import CopyButton from '@/components/copy-button';
|
|||||||
import IconFont from '@/components/icon-font';
|
import IconFont from '@/components/icon-font';
|
||||||
import ScrollerModal from '@/components/scroller-modal';
|
import ScrollerModal from '@/components/scroller-modal';
|
||||||
import { GPUSTACK_API_BASE_URL } from '@/config/settings';
|
import { GPUSTACK_API_BASE_URL } from '@/config/settings';
|
||||||
|
import {
|
||||||
|
AUDIO_SPEECH_TO_TEXT_API,
|
||||||
|
AUDIO_TEXT_TO_SPEECH_API,
|
||||||
|
CHAT_API,
|
||||||
|
CREAT_IMAGE_API,
|
||||||
|
EMBEDDING_API,
|
||||||
|
MODEL_PROXY,
|
||||||
|
RERANKER_API
|
||||||
|
} from '@/pages/playground/apis';
|
||||||
import { BulbOutlined } from '@ant-design/icons';
|
import { BulbOutlined } from '@ant-design/icons';
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Button, Tag } from 'antd';
|
import { Button, Tag } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { modelCategoriesMap } from '../config';
|
import { modelCategoriesMap } from '../config';
|
||||||
|
import { ListItem } from '../config/types';
|
||||||
|
|
||||||
const GPUSTACK_API = GPUSTACK_API_BASE_URL;
|
const GPUSTACK_API = GPUSTACK_API_BASE_URL;
|
||||||
|
|
||||||
|
const API_MAP: Record<string, { api: string }> = {
|
||||||
|
[modelCategoriesMap.embedding]: {
|
||||||
|
api: EMBEDDING_API
|
||||||
|
},
|
||||||
|
[modelCategoriesMap.llm]: {
|
||||||
|
api: CHAT_API
|
||||||
|
},
|
||||||
|
[modelCategoriesMap.image]: {
|
||||||
|
api: CREAT_IMAGE_API
|
||||||
|
},
|
||||||
|
[modelCategoriesMap.text_to_speech]: {
|
||||||
|
api: AUDIO_TEXT_TO_SPEECH_API
|
||||||
|
},
|
||||||
|
[modelCategoriesMap.speech_to_text]: {
|
||||||
|
api: AUDIO_SPEECH_TO_TEXT_API
|
||||||
|
},
|
||||||
|
[modelCategoriesMap.reranker]: {
|
||||||
|
api: RERANKER_API
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const ApiAccessInfoWrapper = styled.div`
|
const ApiAccessInfoWrapper = styled.div`
|
||||||
display: grid;
|
display: grid;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
@@ -59,7 +91,7 @@ const CreateButton = styled(Button)`
|
|||||||
|
|
||||||
interface ApiAccessInfoProps {
|
interface ApiAccessInfoProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
data: any;
|
data: ListItem;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +99,21 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
|
|||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const endPoint = `${window.location.origin}/${GPUSTACK_API}`;
|
const getModelCategory = useMemoizedFn((categories: string[]) => {
|
||||||
|
for (const [category, config] of Object.entries(API_MAP)) {
|
||||||
|
if (categories.includes(category)) {
|
||||||
|
return `${MODEL_PROXY}${config.api}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return `${MODEL_PROXY}${CHAT_API}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const endPoint = useMemo(() => {
|
||||||
|
if (!data.generic_proxy) {
|
||||||
|
return `${window.location.origin}/${GPUSTACK_API}`;
|
||||||
|
}
|
||||||
|
return getModelCategory(data.categories || []);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
const isRanker = useMemo(() => {
|
const isRanker = useMemo(() => {
|
||||||
return _.includes(data.categories, modelCategoriesMap.reranker);
|
return _.includes(data.categories, modelCategoriesMap.reranker);
|
||||||
@@ -113,9 +159,13 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
|
|||||||
<BulbOutlined />
|
<BulbOutlined />
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{intl.formatMessage({
|
{data.generic_proxy
|
||||||
id: 'models.table.button.apiAccessInfo.tips'
|
? intl.formatMessage({
|
||||||
})}
|
id: 'models.table.genericProxy'
|
||||||
|
})
|
||||||
|
: intl.formatMessage({
|
||||||
|
id: 'models.table.button.apiAccessInfo.tips'
|
||||||
|
})}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</Tips>
|
</Tips>
|
||||||
@@ -127,13 +177,17 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
|
|||||||
<AutoTooltip ghost maxWidth={180}>
|
<AutoTooltip ghost maxWidth={180}>
|
||||||
{endPoint}
|
{endPoint}
|
||||||
</AutoTooltip>
|
</AutoTooltip>
|
||||||
<APITAG color="geekblue">
|
{!data.generic_proxy && (
|
||||||
{intl.formatMessage({
|
<APITAG color="geekblue">
|
||||||
id: isRanker
|
{isRanker
|
||||||
? 'models.table.apiAccessInfo.jinaCompatible'
|
? intl.formatMessage({
|
||||||
: 'models.table.apiAccessInfo.openaiCompatible'
|
id: 'models.table.apiAccessInfo.jinaCompatible'
|
||||||
})}
|
})
|
||||||
</APITAG>
|
: intl.formatMessage({
|
||||||
|
id: 'models.table.apiAccessInfo.openaiCompatible'
|
||||||
|
})}
|
||||||
|
</APITAG>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="copy-btn">
|
<span className="copy-btn">
|
||||||
<CopyButton text={endPoint} type="link" size="small"></CopyButton>
|
<CopyButton text={endPoint} type="link" size="small"></CopyButton>
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ import {
|
|||||||
SourceType
|
SourceType
|
||||||
} from '../config/types';
|
} from '../config/types';
|
||||||
import useFormInitialValues from '../hooks/use-form-initial-values';
|
import useFormInitialValues from '../hooks/use-form-initial-values';
|
||||||
import useGenericProxy from '../hooks/use-generic-proxy';
|
|
||||||
import useModelsColumns from '../hooks/use-models-columns';
|
import useModelsColumns from '../hooks/use-models-columns';
|
||||||
import AccessControlModal from './access-control-modal';
|
import AccessControlModal from './access-control-modal';
|
||||||
import APIAccessInfoModal from './api-access-info';
|
import APIAccessInfoModal from './api-access-info';
|
||||||
@@ -196,8 +195,6 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
});
|
});
|
||||||
const modalRef = useRef<any>(null);
|
const modalRef = useRef<any>(null);
|
||||||
|
|
||||||
const { GenericProxyModal, openProxyModal } = useGenericProxy();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (deleteIds?.length) {
|
if (deleteIds?.length) {
|
||||||
rowSelection.removeSelectedKey(deleteIds);
|
rowSelection.removeSelectedKey(deleteIds);
|
||||||
@@ -429,12 +426,7 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
const handleViewAPIInfo = useCallback((row: ListItem) => {
|
const handleViewAPIInfo = useCallback((row: ListItem) => {
|
||||||
setAPIAccessInfo({
|
setAPIAccessInfo({
|
||||||
show: true,
|
show: true,
|
||||||
data: {
|
data: row
|
||||||
id: row.id,
|
|
||||||
name: row.name,
|
|
||||||
categories: row.categories,
|
|
||||||
url: `${MODELS_API}/${row.id}/instances`
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
const handleSelect = useMemoizedFn(async (val: any, row: ListItem) => {
|
const handleSelect = useMemoizedFn(async (val: any, row: ListItem) => {
|
||||||
@@ -459,10 +451,6 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
handleViewAPIInfo(row);
|
handleViewAPIInfo(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val === 'proxy') {
|
|
||||||
openProxyModal(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val === 'stop') {
|
if (val === 'stop') {
|
||||||
modalRef.current?.show({
|
modalRef.current?.show({
|
||||||
content: 'models.instances',
|
content: 'models.instances',
|
||||||
@@ -796,7 +784,6 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
currentData={openAccessControlModal.currentData}
|
currentData={openAccessControlModal.currentData}
|
||||||
action={openAccessControlModal.action}
|
action={openAccessControlModal.action}
|
||||||
></AccessControlModal>
|
></AccessControlModal>
|
||||||
{GenericProxyModal}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import icons from '@/components/icon-font/icons';
|
import icons from '@/components/icon-font/icons';
|
||||||
import HotKeys from '@/config/hotkeys';
|
import HotKeys from '@/config/hotkeys';
|
||||||
import _ from 'lodash';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { modelCategoriesMap, modelSourceMap } from './index';
|
import { modelCategoriesMap, modelSourceMap } from './index';
|
||||||
|
|
||||||
@@ -50,11 +49,6 @@ export const ActionList: ActionItem[] = [
|
|||||||
key: 'chat',
|
key: 'chat',
|
||||||
icon: icons.ExperimentOutlined
|
icon: icons.ExperimentOutlined
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: 'models.form.generic_proxy.button',
|
|
||||||
key: 'proxy',
|
|
||||||
icon: icons.CaptivePortal
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'models.table.button.apiAccessInfo',
|
label: 'models.table.button.apiAccessInfo',
|
||||||
key: 'api',
|
key: 'api',
|
||||||
@@ -157,27 +151,6 @@ export const generateSource = (record: any) => {
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setModelActionList = (record: any) => {
|
|
||||||
return _.filter(ActionList, (action: any) => {
|
|
||||||
if (action.key === 'chat' || action.key === 'api') {
|
|
||||||
return record.ready_replicas > 0;
|
|
||||||
}
|
|
||||||
if (action.key === 'start') {
|
|
||||||
return record.replicas === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action.key === 'stop') {
|
|
||||||
return record.replicas > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action.key === 'proxy') {
|
|
||||||
return record.generic_proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const modelFileActions = [
|
export const modelFileActions = [
|
||||||
{
|
{
|
||||||
label: 'common.button.deploy',
|
label: 'common.button.deploy',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export interface ListItem {
|
|||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
access_policy: 'public' | 'authed' | 'allowed_users';
|
access_policy: 'public' | 'authed' | 'allowed_users';
|
||||||
|
generic_proxy?: boolean;
|
||||||
gpu_selector?: {
|
gpu_selector?: {
|
||||||
gpu_ids: string[];
|
gpu_ids: string[];
|
||||||
gpus_per_replica?: number;
|
gpus_per_replica?: number;
|
||||||
|
|||||||
@@ -1,181 +0,0 @@
|
|||||||
import ScrollerModal from '@/components/scroller-modal';
|
|
||||||
import CommandViewer from '@/pages/_components/command-viewer';
|
|
||||||
import {
|
|
||||||
AUDIO_SPEECH_TO_TEXT_API,
|
|
||||||
AUDIO_TEXT_TO_SPEECH_API,
|
|
||||||
CHAT_API,
|
|
||||||
CREAT_IMAGE_API,
|
|
||||||
EMBEDDING_API,
|
|
||||||
MODEL_PROXY,
|
|
||||||
RERANKER_API
|
|
||||||
} from '@/pages/playground/apis';
|
|
||||||
import {
|
|
||||||
generateSpeechToTextCurlCode,
|
|
||||||
generateTextToSpeechCurlCode
|
|
||||||
} from '@/pages/playground/view-code/audio';
|
|
||||||
import { generateEmbeddingCurlCode } from '@/pages/playground/view-code/embedding';
|
|
||||||
import { generateImageCurlCode } from '@/pages/playground/view-code/image';
|
|
||||||
import { generateLLmCurlCode } from '@/pages/playground/view-code/llm';
|
|
||||||
import { generateRerankCurlCode } from '@/pages/playground/view-code/rerank';
|
|
||||||
import { useIntl } from '@umijs/max';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { modelCategoriesMap } from '../config';
|
|
||||||
|
|
||||||
const API_MAP: Record<
|
|
||||||
string,
|
|
||||||
{ api: string; parameters: any; generateCurlCode: (args: any) => string }
|
|
||||||
> = {
|
|
||||||
[modelCategoriesMap.embedding]: {
|
|
||||||
api: EMBEDDING_API,
|
|
||||||
parameters: {
|
|
||||||
query: 'What are the benefits of regular exercise?',
|
|
||||||
documents: [
|
|
||||||
'Regular physical activity helps improve cardiovascular health and mental well-being.',
|
|
||||||
'Eating too much sugar can lead to health issues.',
|
|
||||||
'Exercise is often done in gyms or outdoors.'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
generateCurlCode: generateEmbeddingCurlCode
|
|
||||||
},
|
|
||||||
[modelCategoriesMap.llm]: {
|
|
||||||
api: CHAT_API,
|
|
||||||
parameters: {
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
role: 'user',
|
|
||||||
content: 'Hello, introduce yourself'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
generateCurlCode: generateLLmCurlCode
|
|
||||||
},
|
|
||||||
[modelCategoriesMap.image]: {
|
|
||||||
api: CREAT_IMAGE_API,
|
|
||||||
parameters: {},
|
|
||||||
generateCurlCode: generateImageCurlCode
|
|
||||||
},
|
|
||||||
[modelCategoriesMap.text_to_speech]: {
|
|
||||||
api: AUDIO_TEXT_TO_SPEECH_API,
|
|
||||||
parameters: {
|
|
||||||
response_format: 'mp3',
|
|
||||||
input: ''
|
|
||||||
},
|
|
||||||
generateCurlCode: generateTextToSpeechCurlCode
|
|
||||||
},
|
|
||||||
[modelCategoriesMap.speech_to_text]: {
|
|
||||||
api: AUDIO_SPEECH_TO_TEXT_API,
|
|
||||||
parameters: {},
|
|
||||||
generateCurlCode: generateSpeechToTextCurlCode
|
|
||||||
},
|
|
||||||
[modelCategoriesMap.reranker]: {
|
|
||||||
api: RERANKER_API,
|
|
||||||
parameters: {
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
role: 'user',
|
|
||||||
content: 'Hello, introduce yourself'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
generateCurlCode: generateRerankCurlCode
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const langOptions = [{ label: 'Curl', value: 'bash' }];
|
|
||||||
|
|
||||||
const useGenericProxy = () => {
|
|
||||||
const intl = useIntl();
|
|
||||||
const [modalStatus, setModalStatus] = useState<{
|
|
||||||
open: boolean;
|
|
||||||
codeValue: string;
|
|
||||||
}>({ open: false, codeValue: '' });
|
|
||||||
|
|
||||||
const onCancel = () => {
|
|
||||||
setModalStatus({
|
|
||||||
open: false,
|
|
||||||
codeValue: ''
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getModelCategory = (categories: string[]) => {
|
|
||||||
for (const [category, config] of Object.entries(API_MAP)) {
|
|
||||||
if (categories.includes(category)) {
|
|
||||||
return {
|
|
||||||
category,
|
|
||||||
api: `${MODEL_PROXY}${config.api}`,
|
|
||||||
parameters: config.parameters,
|
|
||||||
generateCurlCode: config.generateCurlCode
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
category: modelCategoriesMap.llm,
|
|
||||||
api: CHAT_API,
|
|
||||||
parameters: {
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
role: 'user',
|
|
||||||
content: 'Hello, introduce yourself'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
generateCurlCode: generateLLmCurlCode
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const openProxyModal = (data?: any) => {
|
|
||||||
const { api, generateCurlCode, parameters } = getModelCategory(
|
|
||||||
data?.categories || []
|
|
||||||
);
|
|
||||||
|
|
||||||
setModalStatus({
|
|
||||||
open: true,
|
|
||||||
codeValue: generateCurlCode({
|
|
||||||
api,
|
|
||||||
modelProxy: true,
|
|
||||||
parameters: {
|
|
||||||
model: data?.name || '',
|
|
||||||
...parameters
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const GenericProxyModal = (
|
|
||||||
<ScrollerModal
|
|
||||||
title={intl.formatMessage({
|
|
||||||
id: 'models.form.generic_proxy.button'
|
|
||||||
})}
|
|
||||||
open={modalStatus.open}
|
|
||||||
centered={true}
|
|
||||||
onCancel={onCancel}
|
|
||||||
destroyOnHidden={true}
|
|
||||||
closeIcon={true}
|
|
||||||
maskClosable={false}
|
|
||||||
keyboard={false}
|
|
||||||
width={700}
|
|
||||||
footer={false}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{ marginBottom: 8 }}
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: intl.formatMessage({ id: 'models.table.genericProxy' })
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<CommandViewer
|
|
||||||
code={modalStatus.codeValue}
|
|
||||||
copyText={modalStatus.codeValue}
|
|
||||||
options={langOptions}
|
|
||||||
defaultValue={'bash'}
|
|
||||||
></CommandViewer>
|
|
||||||
</ScrollerModal>
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
GenericProxyModal,
|
|
||||||
openProxyModal,
|
|
||||||
setModalStatus
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useGenericProxy;
|
|
||||||
@@ -8,11 +8,30 @@ import { useIntl } from '@umijs/max';
|
|||||||
import { Tooltip } from 'antd';
|
import { Tooltip } from 'antd';
|
||||||
import type { SortOrder } from 'antd/es/table/interface';
|
import type { SortOrder } from 'antd/es/table/interface';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import _ from 'lodash';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import ModelTag from '../components/model-tag';
|
import ModelTag from '../components/model-tag';
|
||||||
import { generateSource, setModelActionList } from '../config/button-actions';
|
import { ActionList, generateSource } from '../config/button-actions';
|
||||||
import { ListItem } from '../config/types';
|
import { ListItem } from '../config/types';
|
||||||
|
|
||||||
|
const setModelActionList = (record: any) => {
|
||||||
|
return _.filter(ActionList, (action: any) => {
|
||||||
|
if (action.key === 'chat' || action.key === 'api') {
|
||||||
|
return record.ready_replicas > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.key === 'start') {
|
||||||
|
return record.replicas === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.key === 'stop') {
|
||||||
|
return record.replicas > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
interface ModelsColumnsHookProps {
|
interface ModelsColumnsHookProps {
|
||||||
handleSelect: (val: string, record: ListItem) => void;
|
handleSelect: (val: string, record: ListItem) => void;
|
||||||
sortOrder: SortOrder;
|
sortOrder: SortOrder;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis';
|
import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis';
|
||||||
import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils';
|
import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils';
|
||||||
|
|
||||||
@@ -15,8 +16,9 @@ export const generateSpeechToTextCurlCode = ({
|
|||||||
curl ${host}${api} \\
|
curl ${host}${api} \\
|
||||||
-H "Content-Type: multipart/form-data" \\
|
-H "Content-Type: multipart/form-data" \\
|
||||||
-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''}
|
-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''}
|
||||||
|
-F model="${parameters.model}" \\
|
||||||
-F file="@/path/to/file/audio.mp3;type=audio/mpeg" \\
|
-F file="@/path/to/file/audio.mp3;type=audio/mpeg" \\
|
||||||
${formatCurlArgs(parameters, true)}`
|
${formatCurlArgs(_.omit(parameters, 'model'), true)}`
|
||||||
.trim()
|
.trim()
|
||||||
.replace(/\\$/g, '');
|
.replace(/\\$/g, '');
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export const GPUsConfigs: Record<
|
|||||||
[GPUDriverMap.ILUVATAR]: {
|
[GPUDriverMap.ILUVATAR]: {
|
||||||
label: ManufacturerMap[GPUDriverMap.ILUVATAR],
|
label: ManufacturerMap[GPUDriverMap.ILUVATAR],
|
||||||
value: GPUDriverMap.ILUVATAR,
|
value: GPUDriverMap.ILUVATAR,
|
||||||
runtime: '', // TODO: confirm runtime name
|
runtime: 'iluvatar', // TODO: confirm runtime name
|
||||||
driver: 'ixsmi'
|
driver: 'ixsmi'
|
||||||
},
|
},
|
||||||
[GPUDriverMap.CAMBRICON]: {
|
[GPUDriverMap.CAMBRICON]: {
|
||||||
@@ -136,15 +136,15 @@ const registerWorker = (params: {
|
|||||||
gpu: string;
|
gpu: string;
|
||||||
}) => {
|
}) => {
|
||||||
const config = GPUsConfigs[params.gpu];
|
const config = GPUsConfigs[params.gpu];
|
||||||
return `WORKER_NAME="gpustack-worker" \\
|
return `CONTAINER_NAME="gpustack-worker" \\
|
||||||
WORKER_PORT="80" \\
|
WORKER_PORT="80" \\
|
||||||
WORKER_IP="" \\
|
WORKER_IP="" \\
|
||||||
docker run -d --name \${WORKER_NAME} \\
|
sudo docker run -d --name \${CONTAINER_NAME} \\
|
||||||
--restart=unless-stopped \\
|
--restart=unless-stopped \\
|
||||||
--privileged \\
|
--privileged \\
|
||||||
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${CONTAINER_NAME}" \\
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
||||||
--volume gpustack-data:/var/lib/gpustack \\
|
--volume gpustack-data:/var/lib/gpustack \\
|
||||||
--runtime ${config.runtime} \\
|
--runtime ${config.runtime} \\
|
||||||
@@ -164,19 +164,19 @@ const registerAscendWorker = (params: {
|
|||||||
gpu: string;
|
gpu: string;
|
||||||
}) => {
|
}) => {
|
||||||
const config = GPUsConfigs[params.gpu];
|
const config = GPUsConfigs[params.gpu];
|
||||||
return `WORKER_NAME="gpustack-worker" \\
|
return `CONTAINER_NAME="gpustack-worker" \\
|
||||||
WORKER_PORT="80" \\
|
WORKER_PORT="80" \\
|
||||||
WORKER_IP="" \\
|
WORKER_IP="" \\
|
||||||
docker run -d --name \${WORKER_NAME} \\
|
sudo docker run -d --name \${CONTAINER_NAME} \\
|
||||||
--restart=unless-stopped \\
|
--restart=unless-stopped \\
|
||||||
--privileged \\
|
--privileged \\
|
||||||
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${CONTAINER_NAME}" \\
|
||||||
|
--env "ASCEND_VISIBLE_DEVICES=$(npu-smi info -m | tail -n 1 | awk '{print $1}') \\
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
||||||
--volume gpustack-data:/var/lib/gpustack \\
|
--volume gpustack-data:/var/lib/gpustack \\
|
||||||
--runtime ${config.runtime} \\
|
--runtime ${config.runtime} \\
|
||||||
--env "ASCEND_VISIBLE_DEVICES=$(npu-smi info -m | tail -n 1 | awk '{print $1}') \\
|
|
||||||
${params.image} \\
|
${params.image} \\
|
||||||
--server-url ${params.server} \\
|
--server-url ${params.server} \\
|
||||||
--token ${params.token} \\
|
--token ${params.token} \\
|
||||||
@@ -192,21 +192,21 @@ const registerHygonWorker = (params: {
|
|||||||
gpu: string;
|
gpu: string;
|
||||||
}) => {
|
}) => {
|
||||||
const config = GPUsConfigs[params.gpu];
|
const config = GPUsConfigs[params.gpu];
|
||||||
return `WORKER_NAME="gpustack-worker" \\
|
return `CONTAINER_NAME="gpustack-worker" \\
|
||||||
WORKER_PORT="80" \\
|
WORKER_PORT="80" \\
|
||||||
WORKER_IP="" \\
|
WORKER_IP="" \\
|
||||||
docker run -d --name \${WORKER_NAME} \\
|
sudo docker run -d --name \${CONTAINER_NAME} \\
|
||||||
--restart=unless-stopped \\
|
--restart=unless-stopped \\
|
||||||
--privileged \\
|
--privileged \\
|
||||||
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${CONTAINER_NAME}" \\
|
||||||
|
--env ROCM_PATH=/opt/dtk \\
|
||||||
|
--env ROCM_SMI_LIB_PATH=/opt/hyhal/lib \\
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
||||||
--volume gpustack-data:/var/lib/gpustack \\
|
--volume gpustack-data:/var/lib/gpustack \\
|
||||||
--runtime ${config.runtime} \\
|
|
||||||
--volume /opt/hyhal:/opt/hyhal:ro \\
|
--volume /opt/hyhal:/opt/hyhal:ro \\
|
||||||
--volume /opt/dtk:/opt/dtk:ro \\
|
--volume /opt/dtk:/opt/dtk:ro \\
|
||||||
--env ROCM_PATH=/opt/dtk \\
|
|
||||||
${params.image} \\
|
${params.image} \\
|
||||||
--server-url ${params.server} \\
|
--server-url ${params.server} \\
|
||||||
--token ${params.token} \\
|
--token ${params.token} \\
|
||||||
@@ -222,20 +222,21 @@ const registerIluvatarWorker = (params: {
|
|||||||
gpu: string;
|
gpu: string;
|
||||||
}) => {
|
}) => {
|
||||||
const config = GPUsConfigs[params.gpu];
|
const config = GPUsConfigs[params.gpu];
|
||||||
return `WORKER_NAME="gpustack-worker" \\
|
return `CONTAINER_NAME="gpustack-worker" \\
|
||||||
WORKER_PORT="80" \\
|
WORKER_PORT="80" \\
|
||||||
WORKER_IP="" \\
|
WORKER_IP="" \\
|
||||||
docker run -d --name \${WORKER_NAME} \\
|
sudo docker run -d --name \${CONTAINER_NAME} \\
|
||||||
--restart=unless-stopped \\
|
--restart=unless-stopped \\
|
||||||
--privileged \\
|
--privileged \\
|
||||||
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${CONTAINER_NAME}" \\
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
||||||
--volume gpustack-data:/var/lib/gpustack \\
|
--volume gpustack-data:/var/lib/gpustack \\
|
||||||
--volume /lib/modules:/lib/modules:ro \\
|
--volume /lib/modules:/lib/modules:ro \\
|
||||||
--volume /usr/local/corex:/usr/local/corex:ro \\
|
--volume /usr/local/corex:/usr/local/corex:ro \\
|
||||||
--volume /usr/bin/ixsmi:/usr/bin/ixsmi \\
|
--volume /usr/bin/ixsmi:/usr/bin/ixsmi \\
|
||||||
|
--runtime ${config.runtime} \\
|
||||||
${params.image} \\
|
${params.image} \\
|
||||||
--server-url ${params.server} \\
|
--server-url ${params.server} \\
|
||||||
--token ${params.token} \\
|
--token ${params.token} \\
|
||||||
@@ -251,15 +252,15 @@ const registerMetaXWorker = (params: {
|
|||||||
gpu: string;
|
gpu: string;
|
||||||
}) => {
|
}) => {
|
||||||
const config = GPUsConfigs[params.gpu];
|
const config = GPUsConfigs[params.gpu];
|
||||||
return `WORKER_NAME="gpustack-worker" \\
|
return `CONTAINER_NAME="gpustack-worker" \\
|
||||||
WORKER_PORT="80" \\
|
WORKER_PORT="80" \\
|
||||||
WORKER_IP="" \\
|
WORKER_IP="" \\
|
||||||
docker run -d --name \${WORKER_NAME} \\
|
sudo docker run -d --name \${CONTAINER_NAME} \\
|
||||||
--restart=unless-stopped \\
|
--restart=unless-stopped \\
|
||||||
--privileged \\
|
--privileged \\
|
||||||
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${CONTAINER_NAME}" \\
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
||||||
--volume gpustack-data:/var/lib/gpustack \\
|
--volume gpustack-data:/var/lib/gpustack \\
|
||||||
--volume /opt/mxdriver:/opt/mxdriver:ro \\
|
--volume /opt/mxdriver:/opt/mxdriver:ro \\
|
||||||
@@ -279,15 +280,15 @@ const registerCambriconWorker = (params: {
|
|||||||
gpu: string;
|
gpu: string;
|
||||||
}) => {
|
}) => {
|
||||||
const config = GPUsConfigs[params.gpu];
|
const config = GPUsConfigs[params.gpu];
|
||||||
return `WORKER_NAME="gpustack-worker" \\
|
return `CONTAINER_NAME="gpustack-worker" \\
|
||||||
WORKER_PORT="80" \\
|
WORKER_PORT="80" \\
|
||||||
WORKER_IP="" \\
|
WORKER_IP="" \\
|
||||||
docker run -d --name \${WORKER_NAME} \\
|
sudo docker run -d --name \${CONTAINER_NAME} \\
|
||||||
--restart=unless-stopped \\
|
--restart=unless-stopped \\
|
||||||
--privileged \\
|
--privileged \\
|
||||||
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
--publish \${WORKER_PORT}:\${WORKER_PORT} \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
|
||||||
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
|
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${CONTAINER_NAME}" \\
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
--volume /var/run/docker.sock:/var/run/docker.sock \\
|
||||||
--volume gpustack-data:/var/lib/gpustack \\
|
--volume gpustack-data:/var/lib/gpustack \\
|
||||||
--volume /usr/local/neuware:/usr/local/neuware:ro \\
|
--volume /usr/local/neuware:/usr/local/neuware:ro \\
|
||||||
@@ -330,7 +331,8 @@ export const AddWorkerDockerNotes: Record<string, string[]> = {
|
|||||||
[GPUDriverMap.HYGON]: [
|
[GPUDriverMap.HYGON]: [
|
||||||
'clusters.addworker.nvidiaNotes-01',
|
'clusters.addworker.nvidiaNotes-01',
|
||||||
'clusters.addworker.nvidiaNotes-02',
|
'clusters.addworker.nvidiaNotes-02',
|
||||||
'clusters.addworker.hygonNotes'
|
'clusters.addworker.hygonNotes',
|
||||||
|
'clusters.addworker.hygonNotes-02'
|
||||||
],
|
],
|
||||||
[GPUDriverMap.ILUVATAR]: [
|
[GPUDriverMap.ILUVATAR]: [
|
||||||
'clusters.addworker.nvidiaNotes-01',
|
'clusters.addworker.nvidiaNotes-01',
|
||||||
|
|||||||
Reference in New Issue
Block a user