From cb98812444e83a6553acb3cdee96ecdeb6b789e7 Mon Sep 17 00:00:00 2001 From: jialin Date: Sun, 29 Dec 2024 18:30:21 +0800 Subject: [PATCH] chore: select multiple gpus by manual --- src/components/auto-tooltip/index.tsx | 40 ++++++++++- src/components/echarts/line-chart.tsx | 6 +- src/hooks/use-chunk-request.ts | 5 ++ .../llmodels/components/advance-config.tsx | 31 +++++--- src/pages/llmodels/components/data-form.tsx | 5 +- src/pages/llmodels/components/gpu-card.tsx | 7 +- src/pages/llmodels/components/table-list.tsx | 12 ++-- .../llmodels/components/update-modal.tsx | 22 +++--- src/pages/llmodels/index.tsx | 72 ++++++++++++------- 9 files changed, 131 insertions(+), 69 deletions(-) diff --git a/src/components/auto-tooltip/index.tsx b/src/components/auto-tooltip/index.tsx index fd6ed519..c6d06637 100644 --- a/src/components/auto-tooltip/index.tsx +++ b/src/components/auto-tooltip/index.tsx @@ -1,3 +1,4 @@ +import { CloseOutlined } from '@ant-design/icons'; import { Tag, Tooltip, type TagProps } from 'antd'; import { throttle } from 'lodash'; import React, { @@ -20,6 +21,7 @@ interface AutoTooltipProps extends Omit { ghost?: boolean; title?: React.ReactNode; showTitle?: boolean; + closable?: boolean; tooltipProps?: React.ComponentProps; } @@ -35,7 +37,6 @@ const AutoTooltip: React.FC = ({ }) => { const contentRef = useRef(null); const [isOverflowing, setIsOverflowing] = useState(false); - const resizeObserver = useRef(); const checkOverflow = useCallback(() => { if (contentRef.current) { @@ -44,6 +45,22 @@ const AutoTooltip: React.FC = ({ } }, [contentRef.current]); + useEffect(() => { + const element = contentRef.current; + if (!element) return; + + const resizeObserver = new ResizeObserver(() => { + checkOverflow(); + }); + + resizeObserver.observe(element); + + // Initial check + checkOverflow(); + + return () => resizeObserver.disconnect(); + }, [checkOverflow]); + useEffect(() => { const debouncedCheckOverflow = throttle(checkOverflow, 200); window.addEventListener('resize', debouncedCheckOverflow); @@ -89,11 +106,28 @@ const AutoTooltip: React.FC = ({ {...tooltipProps} > {ghost ? ( -
+
{children}
) : ( - + + } + > {children} )} diff --git a/src/components/echarts/line-chart.tsx b/src/components/echarts/line-chart.tsx index e09e5025..e175f506 100644 --- a/src/components/echarts/line-chart.tsx +++ b/src/components/echarts/line-chart.tsx @@ -81,7 +81,11 @@ const LineChart: React.FC = (props) => { }, yAxis: { ...options.yAxis, - name: yAxisName + name: yAxisName, + nameTextStyle: { + fontSize: 12, + align: 'right' + } }, xAxis: { ...options.xAxis, diff --git a/src/hooks/use-chunk-request.ts b/src/hooks/use-chunk-request.ts index 7554ccf9..dd14175e 100644 --- a/src/hooks/use-chunk-request.ts +++ b/src/hooks/use-chunk-request.ts @@ -247,6 +247,11 @@ const useSetChunkRequest = () => { }, []); useEffect(() => { + console.log( + 'chunkrequest===retryCount.current==', + requestReadyState, + retryCount.current + ); if (requestReadyState === 4 && retryCount.current > 0) { requestConfig.current.beforeReconnect?.(); clearTimeout(timer.current); diff --git a/src/pages/llmodels/components/advance-config.tsx b/src/pages/llmodels/components/advance-config.tsx index bc77c3c9..3c566dd8 100644 --- a/src/pages/llmodels/components/advance-config.tsx +++ b/src/pages/llmodels/components/advance-config.tsx @@ -1,3 +1,4 @@ +import AutoTooltip from '@/components/auto-tooltip'; import LabelSelector from '@/components/label-selector'; import ListInput from '@/components/list-input'; import SealInput from '@/components/seal-form/seal-input'; @@ -5,13 +6,11 @@ import SealSelect from '@/components/seal-form/seal-select'; import { PageActionType } from '@/config/types'; import { InfoCircleOutlined, RightOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; - import { Checkbox, Collapse, Form, FormInstance, - Select, Tooltip, Typography } from 'antd'; @@ -252,7 +251,7 @@ const AdvanceConfig: React.FC = (props) => { id: 'common.form.rule.select' }, { - name: 'gpu_selector' + name: intl.formatMessage({ id: 'models.form.gpuselector' }) } ) } @@ -262,14 +261,24 @@ const AdvanceConfig: React.FC = (props) => { label={intl.formatMessage({ id: 'models.form.gpuselector' })} required mode="multiple" - maxLength={1} - > - {gpuOptions.map((item) => ( - - - - ))} - + maxTagCount={1} + tagRender={(props) => { + return ( + + {props.label} + + ); + }} + options={gpuOptions} + optionRender={(props) => { + return ; + }} + > )} diff --git a/src/pages/llmodels/components/data-form.tsx b/src/pages/llmodels/components/data-form.tsx index 516c7ea9..c7076dfd 100644 --- a/src/pages/llmodels/components/data-form.tsx +++ b/src/pages/llmodels/components/data-form.tsx @@ -85,11 +85,12 @@ const DataForm: React.FC = forwardRef((props, ref) => { const list = _.map(data.items, (item: GPUListItem) => { return { ...item, - label: item.name, + title: '', + label: ` ${item.name}(${item.worker_name})[ + ${intl.formatMessage({ id: 'resources.table.index' })}:${item.index}]`, value: item.id }; }); - console.log('queryGPUList========', list); setGpuOptions(list); }; diff --git a/src/pages/llmodels/components/gpu-card.tsx b/src/pages/llmodels/components/gpu-card.tsx index 90614fbf..ec01fb8b 100644 --- a/src/pages/llmodels/components/gpu-card.tsx +++ b/src/pages/llmodels/components/gpu-card.tsx @@ -14,12 +14,7 @@ const GPUCard: React.FC<{ return (
- {header ?? ( - - {data.label}({data.worker_name})[ - {intl.formatMessage({ id: 'resources.table.index' })}:{data.index}] - - )} + {header ?? {data.label}}
{info ?? ( diff --git a/src/pages/llmodels/components/table-list.tsx b/src/pages/llmodels/components/table-list.tsx index d164c4f8..86aeb379 100644 --- a/src/pages/llmodels/components/table-list.tsx +++ b/src/pages/llmodels/components/table-list.tsx @@ -406,7 +406,7 @@ const Models: React.FC = ({ const handleLogModalCancel = useCallback(() => { setOpenLogModal(false); onCancelViewLogs(); - }, []); + }, [onCancelViewLogs]); const handleDelete = async (row: any) => { modalRef.current.show({ @@ -437,23 +437,23 @@ const Models: React.FC = ({ }; const handleOpenPlayGround = (row: any) => { - if (row.image_only) { + if (row.categories?.includes(modelCategoriesMap.image)) { navigate(`/playground/text-to-image?model=${row.name}`); return; } - if (row.text_to_speech) { + if (row.categories?.includes(modelCategoriesMap.text_to_speech)) { navigate(`/playground/speech?model=${row.name}&type=tts`); return; } - if (row.speech_to_text) { + if (row.categories?.includes(modelCategoriesMap.speech_to_text)) { navigate(`/playground/speech?model=${row.name}&type=stt`); return; } - if (row.reranker) { + if (row.categories?.includes(modelCategoriesMap.reranker)) { navigate(`/playground/rerank?model=${row.name}`); return; } - if (row.embedding_only) { + if (row.categories?.includes(modelCategoriesMap.embedding)) { navigate(`/playground/embedding?model=${row.name}`); return; } diff --git a/src/pages/llmodels/components/update-modal.tsx b/src/pages/llmodels/components/update-modal.tsx index bdf9a004..bbe8558e 100644 --- a/src/pages/llmodels/components/update-modal.tsx +++ b/src/pages/llmodels/components/update-modal.tsx @@ -48,8 +48,10 @@ const UpdateModal: React.FC = (props) => { const list = _.map(data.items, (item: GPUListItem) => { return { ...item, - label: item.name, - value: `${item.worker_name}-${item.name}-${item.index}` + title: '', + label: ` ${item.name}(${item.worker_name})[ + ${intl.formatMessage({ id: 'resources.table.index' })}:${item.index}]`, + value: item.id }; }); setGpuOptions(list); @@ -92,9 +94,9 @@ const UpdateModal: React.FC = (props) => { ? props.data.categories[0] : null, scheduleType: props.data?.gpu_selector ? 'manual' : 'auto', - gpu_selector: props.data?.gpu_selector - ? `${props.data?.gpu_selector.worker_name}-${props.data?.gpu_selector.gpu_name}-${props.data?.gpu_selector.gpu_index}` - : null + gpu_selector: props.data?.gpu_selector || { + gpu_ids: [] + } }; form.setFieldsValue(formData); } @@ -300,19 +302,13 @@ const UpdateModal: React.FC = (props) => { }; } if (formdata.scheduleType === 'manual') { - const gpu = _.find(gpuOptions, (item: any) => { - return item.value === formdata.gpu_selector; - }); - onOk({ ..._.omit(formdata, ['scheduleType']), categories: formdata.categories ? [formdata.categories] : [], worker_selector: null, - gpu_selector: gpu + gpu_selector: formdata.gpu_selector?.gpu_ids?.length ? { - gpu_name: gpu.name, - gpu_index: gpu.index, - worker_name: gpu.worker_name + gpu_ids: formdata.gpu_selector.gpu_ids } : null, ...obj diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx index 622ff0f9..e1a98d1f 100644 --- a/src/pages/llmodels/index.tsx +++ b/src/pages/llmodels/index.tsx @@ -13,8 +13,6 @@ import TableList from './components/table-list'; import { ListItem } from './config/types'; const Models: React.FC = () => { - console.log('model list====1'); - const { setChunkRequest, createAxiosToken } = useSetChunkRequest(); const { setChunkRequest: setModelInstanceChunkRequest } = useSetChunkRequest(); @@ -33,6 +31,7 @@ const Models: React.FC = () => { const [firstLoad, setFirstLoad] = useState(true); const chunkRequedtRef = useRef(); const chunkInstanceRequedtRef = useRef(); + const isPageHidden = useRef(false); let axiosToken = createAxiosToken(); const [queryParams, setQueryParams] = useState({ page: 1, @@ -83,11 +82,13 @@ const Models: React.FC = () => { total: res.pagination.total }); } catch (error) { - setDataSource({ - dataList: [], - loading: false, - total: dataSource.total - }); + if (!isPageHidden.current) { + setDataSource({ + dataList: [], + loading: false, + total: dataSource.total + }); + } console.log('error+++', error); } finally { setFirstLoad(false); @@ -115,7 +116,7 @@ const Models: React.FC = () => { setModelInstances(list); }; - const createModelsChunkRequest = () => { + const createModelsChunkRequest = useCallback(async () => { chunkRequedtRef.current?.current?.cancel?.(); try { chunkRequedtRef.current = setChunkRequest({ @@ -128,8 +129,8 @@ const Models: React.FC = () => { } catch (error) { // ignore } - }; - const createModelsInstanceChunkRequest = () => { + }, [queryParams]); + const createModelsInstanceChunkRequest = useCallback(async () => { chunkInstanceRequedtRef.current?.current?.cancel?.(); try { chunkInstanceRequedtRef.current = setModelInstanceChunkRequest({ @@ -140,7 +141,7 @@ const Models: React.FC = () => { } catch (error) { // ignore } - }; + }, []); const handleSearch = useCallback( (e: any) => { @@ -160,15 +161,22 @@ const Models: React.FC = () => { ); const handleOnViewLogs = useCallback(() => { + isPageHidden.current = true; chunkRequedtRef.current?.current?.cancel?.(); cacheDataListRef.current = []; chunkInstanceRequedtRef.current?.current?.cancel?.(); }, []); - const handleOnCancelViewLogs = useCallback(() => { - createModelsChunkRequest(); - createModelsInstanceChunkRequest(); - }, []); + const handleOnCancelViewLogs = useCallback(async () => { + isPageHidden.current = false; + await Promise.all([ + createModelsChunkRequest(), + createModelsInstanceChunkRequest() + ]); + setTimeout(() => { + fetchData(); + }, 100); + }, [fetchData, createModelsChunkRequest, createModelsInstanceChunkRequest]); useEffect(() => { fetchData(); @@ -193,22 +201,32 @@ const Models: React.FC = () => { createModelsChunkRequest(); createModelsInstanceChunkRequest(); }, 100); - document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible') { - createModelsChunkRequest(); - createModelsInstanceChunkRequest(); - } else { - chunkRequedtRef.current?.current?.cancel?.(); - cacheDataListRef.current = []; - chunkInstanceRequedtRef.current?.current?.cancel?.(); - } - }); } + }, [firstLoad]); + + useEffect(() => { + const handleVisibilityChange = async () => { + if (document.visibilityState === 'visible') { + isPageHidden.current = false; + await Promise.all([ + createModelsChunkRequest(), + createModelsInstanceChunkRequest() + ]); + fetchData(); + } else { + isPageHidden.current = true; + chunkRequedtRef.current?.current?.cancel?.(); + cacheDataListRef.current = []; + chunkInstanceRequedtRef.current?.current?.cancel?.(); + } + }; + + document.addEventListener('visibilitychange', handleVisibilityChange); return () => { - document.removeEventListener('visibilitychange', () => {}); + document.removeEventListener('visibilitychange', handleVisibilityChange); }; - }, [firstLoad]); + }, [fetchData, createModelsChunkRequest, createModelsInstanceChunkRequest]); return (