diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts index b2c1d4be..d2e7d15c 100644 --- a/src/locales/en-US/models.ts +++ b/src/locales/en-US/models.ts @@ -141,7 +141,7 @@ export default { 'models.table.download.progress': 'Download Progress', 'models.table.button.apiAccessInfo': 'API Access Info', 'models.table.button.apiAccessInfo.tips': `To integrate this model with third-party applications, use the following details: access URL, model name, and API key. These credentials are required to ensure proper connection and usage of the model service.`, - 'models.table.apiAccessInfo.enpoint': 'Access URL', + 'models.table.apiAccessInfo.endpoint': 'Access URL', 'models.table.apiAccessInfo.modelName': 'Model Name', 'models.table.apiAccessInfo.apikey': 'API Key', 'models.table.apiAccessInfo.openaiCompatible': 'OpenAI Compatible', diff --git a/src/locales/en-US/resources.ts b/src/locales/en-US/resources.ts index 43c59c19..5617ffb0 100644 --- a/src/locales/en-US/resources.ts +++ b/src/locales/en-US/resources.ts @@ -67,7 +67,7 @@ export default { 'The default storage directory is /var/lib/gpustack/cache, or the directory specified by --cache-dir (preferred) or --data-dir.', 'resources.modelfiles.retry.download': 'Retry Download', 'resources.modelfiles.storagePath.holder': - 'Waiting for the download to complete...', + 'Download in progress: {name}', 'resources.filter.worker': 'Filter by worker', 'resources.filter.source': 'Filter by Source', 'resources.modelfiles.delete.tips': 'Also delete the file from disk!', diff --git a/src/locales/ja-JP/models.ts b/src/locales/ja-JP/models.ts index d9153321..f26c3430 100644 --- a/src/locales/ja-JP/models.ts +++ b/src/locales/ja-JP/models.ts @@ -138,7 +138,7 @@ export default { 'models.table.download.progress': 'Download Progress', 'models.table.button.apiAccessInfo': 'API Access Info', 'models.table.button.apiAccessInfo.tips': `To integrate this model with third-party applications, use the following details: access URL, model name, and API key. These credentials are required to ensure proper connection and usage of the model service.`, - 'models.table.apiAccessInfo.enpoint': 'Access URL', + 'models.table.apiAccessInfo.endpoint': 'Access URL', 'models.table.apiAccessInfo.modelName': 'Model Name', 'models.table.apiAccessInfo.apikey': 'API Key', 'models.table.apiAccessInfo.openaiCompatible': 'OpenAI Compatible', @@ -167,7 +167,7 @@ export default { // 17. 'models.form.check.claims3', // 18. 'models.table.button.apiAccessInfo', // 19. 'models.table.button.apiAccessInfo.tips', -// 20. 'models.table.apiAccessInfo.enpoint', +// 20. 'models.table.apiAccessInfo.endpoint', // 21. 'models.table.apiAccessInfo.modelName', // 22. 'models.table.apiAccessInfo.apikey', // 23. 'models.table.apiAccessInfo.openaiCompatible', diff --git a/src/locales/ja-JP/resources.ts b/src/locales/ja-JP/resources.ts index 5ac7492b..af682beb 100644 --- a/src/locales/ja-JP/resources.ts +++ b/src/locales/ja-JP/resources.ts @@ -68,7 +68,7 @@ export default { 'The default storage directory is /var/lib/gpustack/cache, or the directory specified by --cache-dir (preferred) or --data-dir.', 'resources.modelfiles.retry.download': 'Retry Download', 'resources.modelfiles.storagePath.holder': - 'Waiting for download to complete...', + 'Download in progress: {name}', 'resources.filter.worker': 'Filter by worker', 'resources.filter.source': 'Filter by Source', 'resources.modelfiles.delete.tips': 'Also delete the file from disk!', diff --git a/src/locales/ru-RU/models.ts b/src/locales/ru-RU/models.ts index 88fd688d..30a146d8 100644 --- a/src/locales/ru-RU/models.ts +++ b/src/locales/ru-RU/models.ts @@ -21,7 +21,7 @@ export default { 'model.form.ollama.model': 'Модель Ollama', 'model.form.ollamaholder': 'Выберите или введите название модели', 'model.deploy.sort': 'Сортировка', - 'model.deploy.search.placeholder': 'Введите / для поиска моделей', // Translated + 'model.deploy.search.placeholder': 'Введите / для поиска моделей', 'model.form.ollamatips': 'Подсказка: ниже представлены предустановленные модели Ollama в GPUStack. Выберите нужную или введите модель для развертывания в поле 【{name}】 справа.', 'models.sort.name': 'По имени', @@ -84,9 +84,12 @@ export default { 'models.form.gpuselector': 'Селектор GPU', 'models.form.backend.llamabox': 'Для моделей формата GGUF. Поддержка Linux, macOS и Windows.', - 'models.form.backend.vllm': 'Для моделей не-GGUF формата, поддерживается только в Linux (amd64/x86_64).', // Translated - 'models.form.backend.voxbox': 'Для аудиомоделей не-GGUF формата, поддерживается только на GPU NVIDIA и CPU.', // Translated - 'models.form.backend.mindie': 'Для моделей не-GGUF формата, поддерживается только на Ascend 910B и 310P.', // Translated + 'models.form.backend.vllm': + 'Для моделей не-GGUF формата, поддерживается только в Linux (amd64/x86_64).', + 'models.form.backend.voxbox': + 'Для аудиомоделей не-GGUF формата, поддерживается только на GPU NVIDIA и CPU.', + 'models.form.backend.mindie': + 'Для моделей не-GGUF формата, поддерживается только на Ascend 910B и 310P.', 'models.form.search.gguftips': 'Для воркеров на macOS/Windows отметьте GGUF (для аудиомоделей снимите).', 'models.form.button.addlabel': 'Добавить метку', @@ -129,23 +132,25 @@ export default { 'models.form.restart.onerror.tips': 'При возникновении ошибки система автоматически попытается перезапуститься.', 'models.form.check.params': 'Проверка конфигурации...', - 'models.form.check.passed': 'Проверка совместимости пройдена', // Translated + 'models.form.check.passed': 'Проверка совместимости пройдена', 'models.form.check.claims': 'Модель требует примерно {vram} VRAM и {ram} RAM.', 'models.form.check.claims2': 'Модель требует примерно {vram} VRAM.', 'models.form.check.claims3': 'Модель требует примерно {ram} RAM.', - 'models.form.update.tips': 'Изменения вступят в силу только после удаления и повторного создания инстанса.', // Translated - 'models.table.download.progress': 'Прогресс загрузки', // Translated - 'models.table.button.apiAccessInfo': 'Доступ к API', // Translated + 'models.form.update.tips': + 'Изменения вступят в силу только после удаления и повторного создания инстанса.', + 'models.table.download.progress': 'Прогресс загрузки', + 'models.table.button.apiAccessInfo': 'Доступ к API', 'models.table.button.apiAccessInfo.tips': `Для интеграции этой модели со сторонними приложениями используйте следующие данные: URL доступа, имя модели и ключ API. Эти учетные данные необходимы для обеспечения правильного подключения и использования сервиса модели.`, // Translated - 'models.table.apiAccessInfo.endpoint': 'URL доступа', // Translated & key fixed - 'models.table.apiAccessInfo.modelName': 'Имя модели', // Translated - 'models.table.apiAccessInfo.apikey': 'Ключ API', // Translated - 'models.table.apiAccessInfo.openaiCompatible': 'Совместимо с OpenAI', // Translated - 'models.table.apiAccessInfo.jinaCompatible': 'Совместимо с Jina', // Translated - 'models.table.apiAccessInfo.gotoCreate': 'Перейти к созданию', // Translated - 'models.search.parts': '{n} частей' // Translated (assuming simple plural form) + 'models.table.apiAccessInfo.endpoint': 'URL доступа', + 'models.table.apiAccessInfo.modelName': 'Имя модели', + 'models.table.apiAccessInfo.apikey': 'Ключ API', + 'models.table.apiAccessInfo.openaiCompatible': 'Совместимо с OpenAI', + 'models.table.apiAccessInfo.jinaCompatible': 'Совместимо с Jina', + 'models.table.apiAccessInfo.gotoCreate': 'Перейти к созданию', + 'models.search.parts': '{n} частей' }; + // ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== End of To-Do List ========== diff --git a/src/locales/ru-RU/resources.ts b/src/locales/ru-RU/resources.ts index 98afe5a5..f1e823d5 100644 --- a/src/locales/ru-RU/resources.ts +++ b/src/locales/ru-RU/resources.ts @@ -44,12 +44,14 @@ export default { 'resources.worker.add.step1': 'Получить токен (Запустить на сервере)', 'resources.worker.add.step2': 'Зарегистрировать воркер', - 'resources.worker.add.step2.tips': '(Запустить на добавляемом воркере, token — это значение, полученное на первом шаге.)', // Translated + 'resources.worker.add.step2.tips': + '(Запустить на добавляемом воркере, token — это значение, полученное на первом шаге.)', // Translated 'resources.worker.add.step3': 'После успешной регистрации обновите список воркеров.', 'resources.worker.container.supported': 'Только для Linux.', 'resources.worker.current.version': 'Текущая версия: {version}', - 'resources.worker.driver.install': 'Установите необходимые драйверы и библиотеки перед установкой GPUStack.', // Translated + 'resources.worker.driver.install': + 'Установите необходимые драйверы и библиотеки перед установкой GPUStack.', // Translated 'resources.worker.select.command': 'Выберите метку для генерации команды и скопируйте её.', 'resources.worker.script.install': 'Установка скриптом', @@ -61,9 +63,11 @@ export default { 'resources.modelfiles.size': 'Размер', 'resources.modelfiles.selecttarget': 'Выбрать назначение', 'resources.modelfiles.form.localdir': 'Локальный каталог', - 'resources.modelfiles.form.localdir.tips': 'Каталог хранения по умолчанию — /var/lib/gpustack/cache, или каталог, указанный с помощью --cache-dir (предпочтительно) или --data-dir.', // Translated + 'resources.modelfiles.form.localdir.tips': + 'Каталог хранения по умолчанию — /var/lib/gpustack/cache, или каталог, указанный с помощью --cache-dir (предпочтительно) или --data-dir.', // Translated 'resources.modelfiles.retry.download': 'Повторить загрузку', - 'resources.modelfiles.storagePath.holder': 'Ожидание завершения загрузки...', + 'resources.modelfiles.storagePath.holder': + 'Download in progress: {name}', 'resources.filter.worker': 'Фильтровать по узлу', 'resources.filter.source': 'Фильтровать по источнику', 'resources.modelfiles.delete.tips': 'Также удалить файл с диска!', @@ -72,5 +76,5 @@ export default { }; // ========== To-Do: Translate Keys (Remove After Translation) ========== - +// 1. 'resources.modelfiles.storagePath.holder', // ========== End of To-Do List ========== diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts index 47fed891..1ad76bd1 100644 --- a/src/locales/zh-CN/models.ts +++ b/src/locales/zh-CN/models.ts @@ -134,7 +134,7 @@ export default { 'models.table.download.progress': '下载进度', 'models.table.button.apiAccessInfo': 'API 接入信息', 'models.table.button.apiAccessInfo.tips': `当您需要将本模型与第三方应用集成时,请使用以下信息:接入地址、模型名称和 API 密钥。这些信息是确保外部系统能正确连接并调用模型服务的关键凭证。`, - 'models.table.apiAccessInfo.enpoint': '接入地址', + 'models.table.apiAccessInfo.endpoint': '接入地址', 'models.table.apiAccessInfo.modelName': '模型名称', 'models.table.apiAccessInfo.apikey': 'API 密钥', 'models.table.apiAccessInfo.openaiCompatible': 'OpenAI 兼容', diff --git a/src/locales/zh-CN/resources.ts b/src/locales/zh-CN/resources.ts index 0b49c85a..df06a07b 100644 --- a/src/locales/zh-CN/resources.ts +++ b/src/locales/zh-CN/resources.ts @@ -65,7 +65,8 @@ export default { 'resources.modelfiles.form.localdir.tips': '默认存储目录为 /var/lib/gpustack/cache,或使用 --cache-dir(优先)、--data-dir 指定的目录。', 'resources.modelfiles.retry.download': '重新下载', - 'resources.modelfiles.storagePath.holder': '等待下载完成...', + 'resources.modelfiles.storagePath.holder': + '正在下载:{name}', 'resources.filter.worker': '按 Worker 筛选', 'resources.filter.source': '按来源筛选', 'resources.modelfiles.delete.tips': '同时从磁盘删除文件!', diff --git a/src/pages/llmodels/components/api-access-info.tsx b/src/pages/llmodels/components/api-access-info.tsx index 6828d19c..4ec45e0a 100644 --- a/src/pages/llmodels/components/api-access-info.tsx +++ b/src/pages/llmodels/components/api-access-info.tsx @@ -118,7 +118,7 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => { - {intl.formatMessage({ id: 'models.table.apiAccessInfo.enpoint' })} + {intl.formatMessage({ id: 'models.table.apiAccessInfo.endpoint' })} diff --git a/src/pages/llmodels/components/model-card.tsx b/src/pages/llmodels/components/model-card.tsx index ac374993..84bce061 100644 --- a/src/pages/llmodels/components/model-card.tsx +++ b/src/pages/llmodels/components/model-card.tsx @@ -277,18 +277,21 @@ const ModelCard: React.FC<{ return null; }; - const generateModeScopeImgLink = (imgSrc: string) => { - if (!imgSrc) { + const generateModeScopeImgLink = useCallback( + (imgSrc: string) => { + if (!imgSrc) { + return ''; + } + if (modelSource === modelSourceMap.modelscope_value) { + return `https://modelscope.cn/api/v1/models/${modelData?.name}/repo?Revision=${modelData?.Revision}&View=true&FilePath=${imgSrc}`; + } + if (modelSource === modelSourceMap.huggingface_value) { + return `https://huggingface.co/${modelData?.id}/resolve/main/${imgSrc}`; + } return ''; - } - if (modelSource === modelSourceMap.modelscope_value) { - return `https://modelscope.cn/api/v1/models/${modelData?.name}/repo?Revision=${modelData?.Revision}&View=true&FilePath=${imgSrc}`; - } - if (modelSource === modelSourceMap.huggingface_value) { - return `https://huggingface.co/${modelData?.id}/resolve/main/${imgSrc}`; - } - return ''; - }; + }, + [modelSource, modelData?.name, modelData?.id, modelData?.Revision] + ); useEffect(() => { getModelCardData(); diff --git a/src/pages/llmodels/components/update-modal.tsx b/src/pages/llmodels/components/update-modal.tsx index aa6c1ef2..4bcded39 100644 --- a/src/pages/llmodels/components/update-modal.tsx +++ b/src/pages/llmodels/components/update-modal.tsx @@ -81,12 +81,13 @@ const UpdateModal: React.FC = (props) => { } }; - const handleOnValuesChange = _.debounce((data: any) => { + const handleOnValuesChange = (data: any) => { const formdata = form.getFieldsValue?.(); let alldata = {}; if (formdata.scheduleType === 'manual') { alldata = { ..._.omit(formdata, ['worker_selector']), + env: formdata.env || {}, gpu_selector: formdata.gpu_selector?.gpu_ids?.length > 0 ? originFormData.current?.gpu_selector @@ -95,6 +96,7 @@ const UpdateModal: React.FC = (props) => { } else { alldata = { ..._.omit(formdata, ['gpu_selector']), + env: formdata.env || {}, worker_selector: originFormData.current?.worker_selector || null }; } @@ -113,7 +115,7 @@ const UpdateModal: React.FC = (props) => { }) }); } - }, 300); + }; // voxbox is not support multi gpu const handleSetGPUIds = (backend: string) => { @@ -168,14 +170,14 @@ const UpdateModal: React.FC = (props) => { } const isEndwithGGUF = _.endsWith(value, '.gguf'); const isBlobFile = value.split('/').pop().includes('sha256'); - let backend = backendOptionsMap.llamaBox; - const isVllmOrAscend = [ - backendOptionsMap.vllm, - backendOptionsMap.ascendMindie - ].includes(form.getFieldValue('backend')); + let backend = form.getFieldValue('backend'); - if (!isEndwithGGUF || !isBlobFile) { - backend = isVllmOrAscend ? formData!.backend : backendOptionsMap.vllm; + if ( + !isEndwithGGUF && + !isBlobFile && + backend === backendOptionsMap.llamaBox + ) { + backend = backendOptionsMap.vllm; } form.setFieldValue('backend', backend); handleBackendChange?.(backend); diff --git a/src/pages/llmodels/config/vllm-config.ts b/src/pages/llmodels/config/vllm-config.ts index c62759a7..6a8cc4e2 100644 --- a/src/pages/llmodels/config/vllm-config.ts +++ b/src/pages/llmodels/config/vllm-config.ts @@ -4,6 +4,11 @@ const options = [ value: '--uvicorn-log-level', options: ['debug', 'info', 'warning', 'error', 'critical', 'trace'] }, + { + label: '--disable-uvicorn-access-log', + value: '--disable-uvicorn-access-log', + options: [] + }, { label: '--allow-credentials', value: '--allow-credentials', @@ -59,6 +64,11 @@ const options = [ value: '--ssl-certfile', options: [] }, + { + label: '--enable-ssl-refresh', + value: '--enable-ssl-refresh', + options: [] + }, { label: '--ssl-ca-certs', value: '--ssl-ca-certs', @@ -89,6 +99,11 @@ const options = [ value: '--disable-frontend-multiprocessing', options: [] }, + { + label: '--enable-request-id-headers', + value: '--enable-request-id-headers', + options: [] + }, { label: '--enable-auto-tool-choice', value: '--enable-auto-tool-choice', @@ -104,6 +119,7 @@ const options = [ 'jamba', 'llama3_json', 'granite-20b-fc', + 'phi4_mini_json', 'granite', 'pythonic' ] @@ -118,7 +134,8 @@ const options = [ 'embed', 'classify', 'score', - 'reward' + 'reward', + 'transcription' ] }, { @@ -141,6 +158,11 @@ const options = [ value: '--tokenizer', options: [] }, + { + label: '--hf-config-path', + value: '--hf-config-path', + options: [] + }, { label: '--skip-tokenizer-init', value: '--skip-tokenizer-init', @@ -164,7 +186,7 @@ const options = [ { label: '--tokenizer-mode', value: '--tokenizer-mode', - options: ['auto', 'slow', 'mistral'] + options: ['auto', 'slow', 'mistral', 'custom'] }, { label: '--trust-remote-code', @@ -190,7 +212,8 @@ const options = [ 'gguf', 'bitsandbytes', 'mistral', - 'runai_streamer' + 'runai_streamer', + 'fastsafetensors' ] }, { @@ -213,6 +236,11 @@ const options = [ value: '--config-format', options: ['auto', 'hf', 'mistral'] }, + { + label: '--disable-cascade-attn', + value: '--disable-cascade-attn', + options: [] + }, { label: '--dtype', value: '--dtype', @@ -223,6 +251,16 @@ const options = [ value: '--kv-cache-dtype', options: ['auto', 'fp8', 'fp8_e5m2', 'fp8_e4m3'] }, + { + label: '--disable-chunked-mm-input', + value: '--disable-chunked-mm-input', + options: [] + }, + { + label: 'DISABLE_CHUNKED_MM_INPUT', + value: 'DISABLE_CHUNKED_MM_INPUT', + options: [] + }, { label: '--quantization-param-path', value: '--quantization-param-path', @@ -259,6 +297,16 @@ const options = [ value: '--worker-use-ray', options: [] }, + { + label: '--data-parallel-size', + value: '--data-parallel-size', + options: [] + }, + { + label: '--enable-expert-parallel', + value: '--enable-expert-parallel', + options: [] + }, { label: '--pipeline-parallel-size', value: '--pipeline-parallel-size', @@ -289,6 +337,11 @@ const options = [ value: '--enable-prefix-caching', options: [] }, + { + label: '--prefix-caching-hash-algo', + value: '--prefix-caching-hash-algo', + options: ['builtin', 'sha256'] + }, { label: '--disable-sliding-window', value: '--disable-sliding-window', @@ -334,6 +387,23 @@ const options = [ value: '--max-num-batched-tokens', options: [] }, + { + label: '--max-num-partial-prefills', + value: '--max-num-partial-prefills', + options: [] + }, + + { + label: '--max-long-partial-prefills', + value: '--max-long-partial-prefills', + options: [] + }, + + { + label: '--long-prefill-token-threshold', + value: '--long-prefill-token-threshold', + options: [] + }, { label: '--max-num-seqs', value: '--max-num-seqs', @@ -354,6 +424,17 @@ const options = [ value: '--hf-overrides', options: [] }, + { + label: '--hf-token', + value: '--hf-token', + options: [] + }, + + { + label: 'HF_TOKEN', + value: 'HF_TOKEN', + options: [] + }, { label: '--disable-mm-preprocessor-cache', value: '--disable-mm-preprocessor-cache', @@ -368,23 +449,26 @@ const options = [ 'deepspeedfp', 'tpu_int8', 'fp8', + 'ptpc_fp8', 'fbgemm_fp8', 'modelopt', + 'nvfp4', 'marlin', 'gguf', - 'hqq', 'gptq_marlin_24', 'gptq_marlin', 'awq_marlin', 'gptq', - 'quark', - 'moe_wna16', 'compressed-tensors', 'bitsandbytes', 'qqq', + 'hqq', 'experts_int8', 'neuron_quant', 'ipex', + 'quark', + 'moe_wna16', + 'torchao', 'None' ] }, @@ -506,7 +590,12 @@ const options = [ { label: '--device', value: '--device', - options: ['auto', 'cuda', 'neuron', 'cpu', 'openvino', 'tpu', 'xpu', 'hpu'] + options: ['auto', 'cuda', 'neuron', 'cpu', 'tpu', 'xpu', 'hpu'] + }, + { + label: '--speculative-config', + value: '--speculative-config', + options: [] }, { label: '--num-scheduler-steps', @@ -528,105 +617,31 @@ const options = [ value: '--enable-chunked-prefill', options: [] }, - { - label: '--speculative-model', - value: '--speculative-model', - options: [] - }, - { - label: '--speculative-model-quantization', - value: '--speculative-model-quantization', - options: [ - 'aqlm', - 'awq', - 'deepspeedfp', - 'tpu_int8', - 'fp8', - 'fbgemm_fp8', - 'modelopt', - 'marlin', - 'gguf', - 'gptq_marlin_24', - 'gptq_marlin', - 'awq_marlin', - 'gptq', - 'compressed-tensors', - 'bitsandbytes', - 'qqq', - 'hqq', - 'experts_int8', - 'neuron_quant', - 'ipex', - 'quark', - 'moe_wna16', - 'None' - ] - }, - { - label: '--num-speculative-tokens', - value: '--num-speculative-tokens', - options: [] - }, - { - label: '--speculative-disable-mqa-scorer', - value: '--speculative-disable-mqa-scorer', - options: [] - }, - { - label: '--speculative-draft-tensor-parallel-size', - value: '--speculative-draft-tensor-parallel-size', - options: [] - }, - { - label: '--speculative-max-model-len', - value: '--speculative-max-model-len', - options: [] - }, - { - label: '--speculative-disable-by-batch-size', - value: '--speculative-disable-by-batch-size', - options: [] - }, - { - label: '--ngram-prompt-lookup-max', - value: '--ngram-prompt-lookup-max', - options: [] - }, - { - label: '--ngram-prompt-lookup-min', - value: '--ngram-prompt-lookup-min', - options: [] - }, - { - label: '--spec-decoding-acceptance-method', - value: '--spec-decoding-acceptance-method', - options: ['rejection_sampler', 'typical_acceptance_sampler'] - }, - { - label: '--typical-acceptance-sampler-posterior-threshold', - value: '--typical-acceptance-sampler-posterior-threshold', - options: [] - }, - { - label: '--typical-acceptance-sampler-posterior-alpha', - value: '--typical-acceptance-sampler-posterior-alpha', - options: [] - }, - { - label: '--disable-logprobs-during-spec-decoding', - value: '--disable-logprobs-during-spec-decoding', - options: [] - }, { label: '--model-loader-extra-config', value: '--model-loader-extra-config', options: [] }, + { + label: '--scheduler-cls', + value: '--scheduler-cls', + options: [] + }, + { + label: '--use-tqdm-on-load', + value: '--use-tqdm-on-load', + options: [] + }, { label: '--ignore-patterns', value: '--ignore-patterns', options: [] }, + { + label: '--show-hidden-metrics-for-version', + value: '--show-hidden-metrics-for-version', + options: [] + }, { label: '--preemption-mode', value: '--preemption-mode', @@ -713,6 +728,11 @@ const options = [ value: '--disable-log-requests', options: [] }, + { + label: '--additional-config', + value: '--additional-config', + options: [] + }, { label: '--max-log-len', value: '--max-log-len', @@ -727,6 +747,11 @@ const options = [ label: '--enable-prompt-tokens-details', value: '--enable-prompt-tokens-details', options: [] + }, + { + label: '--enable-server-load-tracking', + value: '--enable-server-load-tracking', + options: [] } ]; diff --git a/src/pages/llmodels/forms/local-path.tsx b/src/pages/llmodels/forms/local-path.tsx index 2179eaf3..9951dde8 100644 --- a/src/pages/llmodels/forms/local-path.tsx +++ b/src/pages/llmodels/forms/local-path.tsx @@ -19,7 +19,7 @@ const LocalPathForm: React.FC = () => { const formInnerCtx = useFormInnerContext(); const source = Form.useWatch('source', form); const { onBackendChange } = formInnerCtx; - const { modelFileOptions, byBuiltIn } = formCtx; + const { byBuiltIn } = formCtx; const { getRuleMessage } = useAppUtils(); const intl = useIntl(); const localPathCache = useRef(form.getFieldValue('local_path') || ''); @@ -35,8 +35,13 @@ const LocalPathForm: React.FC = () => { } const isEndwithGGUF = _.endsWith(value, '.gguf'); const isBlobFile = value.split('/').pop().includes('sha256'); - let backend = backendOptionsMap.llamaBox; - if (!isEndwithGGUF && !isBlobFile) { + let backend = form.getFieldValue('backend'); + + if ( + !isEndwithGGUF && + !isBlobFile && + backend === backendOptionsMap.llamaBox + ) { backend = backendOptionsMap.vllm; } form.setFieldValue('backend', backend); diff --git a/src/pages/resources/components/model-files.tsx b/src/pages/resources/components/model-files.tsx index 84649fe2..539f5764 100644 --- a/src/pages/resources/components/model-files.tsx +++ b/src/pages/resources/components/model-files.tsx @@ -145,6 +145,35 @@ const getWorkerName = ( return worker?.label || ''; }; +const getModelInfo = (record: ListItem) => { + if (record.source === modelSourceMap.huggingface_value) { + return { + title: `${record.huggingface_repo_id}/${record.huggingface_filename}`, + filename: record.huggingface_filename + }; + } + if (record.source === modelSourceMap.modelscope_value) { + return { + title: `${record.model_scope_model_id}/${record.model_scope_file_path}`, + filename: record.model_scope_file_path + }; + } + if (record.source === modelSourceMap.ollama_library_value) { + return { + title: record.ollama_library_model_name, + filename: record.ollama_library_model_name + }; + } + return { + title: record.local_path, + filename: _.split(record.local_path, /[\\/]/).pop() + }; +}; + +const getResolvedPath = (pathList: string[]) => { + return _.split(pathList?.[0], /[\\/]/).pop(); +}; + const InstanceStatusTag = (props: { data: ListItem }) => { const { data } = props; if (!data.state) { @@ -174,6 +203,80 @@ const InstanceStatusTag = (props: { data: ListItem }) => { ); }; +const RenderParts = (props: { record: ListItem }) => { + const { record } = props; + const intl = useIntl(); + const parts = record.resolved_paths || []; + if (parts.length <= 1) { + return null; + } + + const renderItem = () => { + return ( + + {parts.map((item: string, index: number) => { + return
  • {_.split(item, /[\\/]/).pop()}
  • ; + })} +
    + ); + }; + + return ( + + }> + + {record.resolved_paths?.length}{' '} + {intl.formatMessage({ id: 'models.form.files' })} + + + + ); +}; + +const ResolvedPathColumn = (props: { record: ListItem }) => { + const { record } = props; + const intl = useIntl(); + if ( + !record.resolved_paths.length && + record.state === ModelfileStateMap.Downloading + ) { + const modelInfo = getModelInfo(record); + const { title, filename } = modelInfo; + return ( + + + + ); + } + return ( + record.resolved_paths?.length > 0 && ( + + + } + > + {getResolvedPath(record.resolved_paths)} + + + + ) + ); +}; + const ModelFiles = () => { const { getGPUList } = useGenerateFormEditInitialValues(); const { saveScrollHeight, restoreScrollHeight } = useBodyScroll(); @@ -308,34 +411,6 @@ const ModelFiles = () => { }; }; - const renderParts = (record: ListItem) => { - const parts = record.resolved_paths || []; - if (parts.length <= 1) { - return null; - } - - const renderItem = () => { - return ( - - {parts.map((item: string, index: number) => { - return
  • {_.split(item, /[\\/]/).pop()}
  • ; - })} -
    - ); - }; - - return ( - - }> - - {record.resolved_paths?.length}{' '} - {intl.formatMessage({ id: 'models.form.files' })} - - - - ); - }; - const handleSelect = async (val: any, record: ListItem) => { try { if (val === 'delete') { @@ -464,10 +539,6 @@ const ModelFiles = () => { } }; - const getResolvedPath = (pathList: string[]) => { - return _.split(pathList?.[0], /[\\/]/).pop(); - }; - const columns = [ { title: intl.formatMessage({ id: 'models.form.source' }), @@ -509,38 +580,9 @@ const ModelFiles = () => { title: intl.formatMessage({ id: 'resources.modelfiles.form.path' }), dataIndex: 'resolved_paths', width: '35%', - render: (text: string, record: ListItem) => { - if ( - !record.resolved_paths.length && - record.state === ModelfileStateMap.Downloading - ) { - return ( - - {intl.formatMessage({ - id: 'resources.modelfiles.storagePath.holder' - })} - - ); - } - return ( - record.resolved_paths?.length > 0 && ( - - - } - > - {getResolvedPath(record.resolved_paths)} - - {renderParts(record)} - - ) - ); - } + render: (text: string, record: ListItem) => ( + + ) }, { title: intl.formatMessage({ id: 'resources.modelfiles.size' }),