import AutoTooltip from '@/components/auto-tooltip'; import { TooltipOverlayScroller } from '@/components/overlay-scroller'; import SimpleTabel, { ColumnProps } from '@/components/simple-table'; import InfoColumn from '@/components/simple-table/info-column'; import StatusTag from '@/components/status-tag'; import ThemeTag from '@/components/tags-wrapper/theme-tag'; import { InstanceStatusMap, InstanceStatusMapValue, status } from '@/pages/llmodels/config'; import { DistributedServerItem, ModelInstanceListItem as ListItem, ModelInstanceListItem } from '@/pages/llmodels/config/types'; import { convertFileSize } from '@/utils'; import { InfoCircleOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Button, Tooltip } from 'antd'; import { ColumnsType } from 'antd/lib/table'; import _ from 'lodash'; import { useMemo } from 'react'; import styled from 'styled-components'; const GPUIndexWrapper = styled.span` display: flex; flex-direction: column; gap: 2px; `; const StatusWrapper = styled.div` display: flex; align-items: center; gap: 4px; `; const fieldList = [ { label: 'CPU', key: 'cpuoffload', locale: false }, { label: 'GPU', key: 'gpuoffload', locale: false } ]; const renderGpuIndexs = (gpuIndexes: number[]) => { return ( {_.chunk(gpuIndexes, 8).map((item: number[], index: number) => { return {item.join(',')}; })} ); }; const distributeCols: ColumnProps[] = [ { title: 'resources.worker', locale: true, key: 'worker_name', style: { wordBreak: 'break-word' } }, { title: 'IP', key: 'worker_ip', render: ({ row }) => { return row.port ? `${row.worker_ip}:${row.port}` : row.worker_ip; } }, { title: 'models.table.gpuindex', locale: true, key: 'gpu_index', render: ({ row }) => { const list = _.sortBy(row.gpu_index, (item: number) => item); return row.is_main ? ( <> {renderGpuIndexs(list)} (main) ) : ( renderGpuIndexs(list) ); } }, { title: 'models.table.vram.allocated', locale: true, key: 'vram', render: ({ rowIndex, row, dataList }) => { return convertFileSize(row.vram, 1); } } ]; const calcTotalVram = (vram: Record) => { return _.sum(_.values(vram)); }; const renderDistributedServer = ( severList: any[], instanceData: ModelInstanceListItem ) => { // const list = _.map(severList, (item: any) => { // const data = _.find(workerList, { id: item.worker_id }); // return { // worker_name: data?.name, // worker_ip: data?.ip, // port: '', // is_main: false, // vram: calcTotalVram(item.computed_resource_claim?.vram || {}), // gpu_index: _.keys(item.computed_resource_claim?.vram) // }; // }); const mainWorker = [ { worker_name: `${instanceData.worker_name}`, worker_ip: `${instanceData.worker_ip}`, port: '', vram: calcTotalVram(instanceData.computed_resource_claim?.vram || {}), is_main: true, gpu_index: instanceData.gpu_indexes } ]; return (
); }; const DistributionInfo: React.FC<{ instanceData: ModelInstanceListItem; }> = ({ instanceData }) => { const intl = useIntl(); const distributed_servers = instanceData.distributed_servers; const severList: DistributedServerItem[] = distributed_servers?.subordinate_workers || []; if (!severList.length) { return null; } return ( {intl.formatMessage({ id: 'models.table.acrossworker' })} ); }; const OffloadInfo: React.FC<{ instanceData: ListItem; }> = (props) => { const intl = useIntl(); const { instanceData } = props; const total_layers = instanceData.computed_resource_claim?.total_layers; const offload_layers = instanceData.computed_resource_claim?.offload_layers; if (total_layers === offload_layers || !total_layers) { return null; } const offloadData = { cpuoffload: `${ _.subtract( instanceData.computed_resource_claim?.total_layers, instanceData.computed_resource_claim?.offload_layers ) || 0 } ${intl.formatMessage({ id: 'models.table.layers' })}`, gpuoffload: `${instanceData.computed_resource_claim?.offload_layers} ${intl.formatMessage( { id: 'models.table.layers' } )}` }; return ( } > {intl.formatMessage({ id: 'models.table.cpuoffload' })} ); }; const InstanceStatusTag: React.FC<{ instanceData: ListItem; }> = (props) => { const intl = useIntl(); const { instanceData } = props; if (!instanceData.state) { return null; } return ( <> {intl.formatMessage({ id: 'models.list.more.logs' })} ) : null } statusValue={{ status: instanceData.state === InstanceStatusMap.Downloading && instanceData.download_progress === 100 ? status[InstanceStatusMap.Running] : status[instanceData.state], text: InstanceStatusMapValue[instanceData.state], message: instanceData.state === InstanceStatusMap.Downloading && instanceData.download_progress === 100 ? '' : instanceData.state_message }} /> ); }; const useInstanceColumns = (props: { clusterList: Global.BaseOption[]; }): ColumnsType => { const { clusterList } = props; const intl = useIntl(); return useMemo(() => { return [ { title: intl.formatMessage({ id: 'resources.model.instance' }), dataIndex: 'name', width: 240, render: (text: string, record: ListItem) => ( {text} ) }, { title: intl.formatMessage({ id: 'resources.worker' }), dataIndex: 'worker_name', render: (text: string, record: ListItem) => ( {text} ) }, { title: intl.formatMessage({ id: 'models.title' }), dataIndex: 'model_name', render: (text: string, record: ListItem) => ( {text} ) }, { title: intl.formatMessage({ id: 'clusters.title' }), dataIndex: 'cluster_id', render: (text: number, record: ListItem) => ( {clusterList.find((item) => item.value === text)?.label} ) }, { title: intl.formatMessage({ id: 'common.table.status' }), dataIndex: 'state', render: (text: string, record: ListItem) => ( ) } ]; }, [intl, clusterList]); }; export default useInstanceColumns;