mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-11-05 16:05:57 +00:00
feat(ai): improve model preparation and download progress refresh (#14297)
This commit is contained in:
@@ -54,6 +54,7 @@ type ModelInfo struct {
|
||||
}
|
||||
|
||||
type ModelDownloadTaskSearch struct {
|
||||
IDs []uint `json:"ids"`
|
||||
IncludeLocal bool `json:"includeLocal"`
|
||||
DownloadType string `json:"downloadType" validate:"omitempty,oneof=all tokenizer"`
|
||||
PageInfo
|
||||
|
||||
@@ -1238,13 +1238,19 @@ func rebuildApp(appInstall model.AppInstall) error {
|
||||
return handleErr(appInstall, err, "")
|
||||
}
|
||||
buildTask.AddSubTaskWithOps(buildTask.Name, func(t *task.Task) error {
|
||||
t.Log(task.GetTaskName(appInstall.Name, "Stop", task.TaskScopeApp))
|
||||
out, err := compose.Down(appInstall.GetComposePath())
|
||||
t.Log(out)
|
||||
if strings.TrimSpace(out) != "" {
|
||||
t.Log(out)
|
||||
}
|
||||
if err != nil {
|
||||
return handleErr(appInstall, err, out)
|
||||
}
|
||||
t.Log(task.GetTaskName(appInstall.Name, "Run", task.TaskScopeApp))
|
||||
out, err = compose.Up(appInstall.GetComposePath())
|
||||
t.Log(out)
|
||||
if strings.TrimSpace(out) != "" {
|
||||
t.Log(out)
|
||||
}
|
||||
if err != nil {
|
||||
return handleErr(appInstall, err, out)
|
||||
}
|
||||
|
||||
@@ -268,6 +268,9 @@ func (m *ModelDownloaderService) PageTasks(req dto.ModelDownloadTaskSearch) (int
|
||||
return pageModelDownloads(req)
|
||||
}
|
||||
var opts []repo.DBOption
|
||||
if len(req.IDs) > 0 {
|
||||
opts = append(opts, repo.WithByIDs(req.IDs))
|
||||
}
|
||||
if req.DownloadType != "" {
|
||||
opts = append(opts, modelDownloadTaskRepo.WithByDownloadType(req.DownloadType))
|
||||
}
|
||||
@@ -469,6 +472,9 @@ func (m *ModelDownloaderService) deleteLocalModel(target, downloadType string, w
|
||||
|
||||
func pageModelDownloads(req dto.ModelDownloadTaskSearch) (int64, []dto.ModelDownloadTaskItem, error) {
|
||||
var opts []repo.DBOption
|
||||
if len(req.IDs) > 0 {
|
||||
opts = append(opts, repo.WithByIDs(req.IDs))
|
||||
}
|
||||
if req.DownloadType != "" {
|
||||
opts = append(opts, modelDownloadTaskRepo.WithByDownloadType(req.DownloadType))
|
||||
}
|
||||
@@ -502,24 +508,27 @@ func pageModelDownloads(req dto.ModelDownloadTaskSearch) (int64, []dto.ModelDown
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
for _, local := range localByPath {
|
||||
repoID := local.RepoID
|
||||
if repoID == "" {
|
||||
repoID = local.Name
|
||||
if len(req.IDs) == 0 {
|
||||
for _, local := range localByPath {
|
||||
repoID := local.RepoID
|
||||
if repoID == "" {
|
||||
repoID = local.Name
|
||||
}
|
||||
items = append(items, dto.ModelDownloadTaskItem{
|
||||
DownloadType: local.DownloadType,
|
||||
Source: local.Source,
|
||||
RepoID: repoID,
|
||||
TargetDir: local.Path,
|
||||
Status: constant.StatusSuccess,
|
||||
Progress: 100,
|
||||
TotalSize: local.Size,
|
||||
DownloadedSize: local.Size,
|
||||
CreatedAt: local.CreatedAt,
|
||||
LocalModel: &local,
|
||||
})
|
||||
}
|
||||
items = append(items, dto.ModelDownloadTaskItem{
|
||||
DownloadType: local.DownloadType,
|
||||
Source: local.Source,
|
||||
RepoID: repoID,
|
||||
TargetDir: local.Path,
|
||||
Status: constant.StatusSuccess,
|
||||
Progress: 100,
|
||||
TotalSize: local.Size,
|
||||
DownloadedSize: local.Size,
|
||||
CreatedAt: local.CreatedAt,
|
||||
LocalModel: &local,
|
||||
})
|
||||
}
|
||||
|
||||
filtered := items[:0]
|
||||
for _, item := range items {
|
||||
if req.Status != "" && item.Status != req.Status {
|
||||
|
||||
@@ -76,6 +76,7 @@ export namespace ModelDownloader {
|
||||
}
|
||||
|
||||
export interface TaskSearch extends ReqPage {
|
||||
ids?: number[];
|
||||
includeLocal?: boolean;
|
||||
downloadType?: DownloadType | '';
|
||||
info: string;
|
||||
|
||||
@@ -1041,6 +1041,29 @@ const message = {
|
||||
validateImageAvailabilityHelper: 'Generates one minimal image before saving and may incur charges',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'Search and download models',
|
||||
searchHelper:
|
||||
'Find models on ModelScope or Hugging Face, then deploy them or create a Recipe in Model Preparation.',
|
||||
modelScopeSearchHelper: 'Reliable access in mainland China',
|
||||
huggingFaceSearchHelper: 'Extensive model collection',
|
||||
searchPlaceholder: 'Enter a model name or repository ID, e.g. Qwen/Qwen3-8B',
|
||||
popularSearches: 'Popular searches',
|
||||
searchSort: 'Sort by',
|
||||
onlyTokenizer: 'Tokenizer only',
|
||||
downloadStatus: 'Download Status',
|
||||
downloaded: 'Downloaded',
|
||||
alreadyExists: 'Already exists',
|
||||
downloadCompleted: 'Download completed',
|
||||
localFilesMissing: 'Local files not found',
|
||||
ollamaNameHelper:
|
||||
'Enter the full model name from the Ollama library. If no tag is specified, latest is used.',
|
||||
downloadHelper: 'Click “Search” to find and download models from ModelScope and Hugging Face.',
|
||||
serviceHelper:
|
||||
'Connect model services from public clouds, local inference engines, and AI gateways for use by built-in 1Panel agents and external agents such as WorkBuddy.',
|
||||
gpuType: 'GPU Type',
|
||||
vllmVersion: 'vLLM Version',
|
||||
vllmImage: 'vLLM Image',
|
||||
servicePort: 'Service Port',
|
||||
gpuAcceleration: 'GPU acceleration',
|
||||
gpuMode: 'Accelerator selection',
|
||||
gpuAll: 'All accelerators',
|
||||
@@ -1072,7 +1095,13 @@ const message = {
|
||||
approxWeightSize: 'Approx. {0} GB',
|
||||
services: 'Model services',
|
||||
addInstance: 'Add instance',
|
||||
addService: 'Add model service',
|
||||
modelScopeEndpointHelper: 'Used to search and download ModelScope models. Defaults to the official URL.',
|
||||
modelTokenHelper: 'Optional. Use a token with access permissions for private or restricted models.',
|
||||
modelDirHelper: 'Directory for model downloads and the local model list.',
|
||||
featuredModelsHelper:
|
||||
'Official 1Panel featured model catalog. Refresh manually or enable auto-sync every 24 hours. Sync updates only the catalog, without downloading model files.',
|
||||
addInstanceHelper: 'Create a vLLM instance to serve downloaded models.',
|
||||
addService: 'Add',
|
||||
onlineModel: 'Online models',
|
||||
instanceDeployment: 'Deploy by instance',
|
||||
engines: 'Local inference engines',
|
||||
@@ -1094,11 +1123,11 @@ const message = {
|
||||
recipeArguments: 'Launch arguments',
|
||||
recipeImportCommand: 'Import command',
|
||||
recipeImportPlaceholder:
|
||||
'Paste a pip/uv or Docker launch command here. 1Panel will automatically parse it and fill in the Recipe.',
|
||||
'Paste a pip/uv or docker launch command here. 1Panel will automatically parse it and fill in the form.',
|
||||
recipeVariablesNotSupported:
|
||||
'Variable references are not supported in commands. Use explicit values; configure environment variables in the environment field.',
|
||||
recipeImportError:
|
||||
'Unable to convert. Include a Docker or vllm serve launch command with a model; paste pip/uv installation commands together with the launch command.',
|
||||
'No valid launch command detected. Paste a pip/uv or docker command that includes a model.',
|
||||
engineProvider: 'Engine / Provider',
|
||||
endpoint: 'Endpoint',
|
||||
cloudAccount: 'Cloud account',
|
||||
@@ -1109,7 +1138,8 @@ const message = {
|
||||
model: 'Models',
|
||||
localModel: 'Local Models',
|
||||
create_helper: 'Pull "{0}"',
|
||||
ollama_doc: 'You can visit the Ollama official website to search and find more models.',
|
||||
ollama_doc:
|
||||
'Find models at {link}. The model will be pulled automatically after adding it. Make sure Ollama is running and sufficient disk space is available.',
|
||||
container_conn_helper: 'Use this address for inter-container access or connection',
|
||||
from_remote: 'This model was not downloaded via 1Panel, no related pull logs.',
|
||||
no_logs: 'The pull logs for this model have been deleted and cannot be viewed.',
|
||||
@@ -1129,7 +1159,7 @@ const message = {
|
||||
'Container address is for agent containers; 127.0.0.1, system IP, or custom address is for AI Gateway or external services.',
|
||||
containerAddress: 'Container address',
|
||||
customAddress: 'Custom address',
|
||||
downloader: 'Downloads',
|
||||
downloader: 'Model Downloads',
|
||||
modelDirectoryHelper:
|
||||
'The model list defaults to the model directory configured in Model Preparation > Settings and shows models downloaded to that directory.',
|
||||
modelDirectoryPlaceholder: 'Search models or enter a full path',
|
||||
@@ -1140,8 +1170,7 @@ const message = {
|
||||
endpointLabel: '{0} endpoint',
|
||||
acceleratedEndpointLabel: '{0} acceleration endpoint',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper:
|
||||
'Configure an acceleration endpoint when HuggingFace access is unstable. Search, details, and downloads will use it.',
|
||||
hfEndpointHelper: 'Optional mirror URL for HuggingFace model searches, details, and downloads.',
|
||||
sortDefault: 'Default sort',
|
||||
sortMostParameters: 'Most parameters',
|
||||
sortLeastParameters: 'Least parameters',
|
||||
@@ -5046,7 +5075,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'Enter the complete startup command, for example: npm run start. For PM2 startup commands, please replace with pm2-runtime, otherwise it will fail to start.',
|
||||
portError: "Don't repeat the same port.",
|
||||
systemRestartHelper: 'Status description: Interruption - status acquisition failed due to system restart',
|
||||
javaScriptHelper: 'Provide a full startup command. For example, "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'The directory must contain jar files, subdirectories are also acceptable',
|
||||
goHelper: 'Provide a full startup command. For example, "go run main.go" or "./main".',
|
||||
|
||||
@@ -1043,6 +1043,29 @@ const message = {
|
||||
validateImageAvailabilityHelper: 'Genera una imagen mínima antes de guardar y puede generar costes',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'Buscar y descargar modelos',
|
||||
searchHelper:
|
||||
'Busca modelos en ModelScope o Hugging Face y luego despliégalos o crea una Recipe en Preparación de modelos.',
|
||||
modelScopeSearchHelper: 'Acceso estable en China continental',
|
||||
huggingFaceSearchHelper: 'Amplia colección de modelos',
|
||||
searchPlaceholder: 'Introduce el nombre o ID del repositorio, p. ej. Qwen/Qwen3-8B',
|
||||
popularSearches: 'Búsquedas populares',
|
||||
searchSort: 'Ordenar por',
|
||||
onlyTokenizer: 'Solo tokenizador',
|
||||
downloadStatus: 'Estado de descarga',
|
||||
downloaded: 'Descargado',
|
||||
alreadyExists: 'Ya existe',
|
||||
downloadCompleted: 'Descarga completada',
|
||||
localFilesMissing: 'No se encontraron los archivos locales',
|
||||
ollamaNameHelper:
|
||||
'Introduzca el nombre completo del modelo de la biblioteca de Ollama. Si no especifica una etiqueta, se usará latest.',
|
||||
downloadHelper: 'Haga clic en «Buscar» para encontrar y descargar modelos de ModelScope y Hugging Face.',
|
||||
serviceHelper:
|
||||
'Conecte servicios de modelos de nubes públicas, motores de inferencia locales y puertas de enlace de IA para que los utilicen los agentes integrados de 1Panel y agentes externos como WorkBuddy.',
|
||||
gpuType: 'Tipo de GPU',
|
||||
vllmVersion: 'Versión de vLLM',
|
||||
vllmImage: 'Imagen de vLLM',
|
||||
servicePort: 'Puerto del servicio',
|
||||
gpuAcceleration: 'Aceleración GPU',
|
||||
gpuMode: 'Selección de aceleradores',
|
||||
gpuAll: 'Todos los aceleradores',
|
||||
@@ -1074,7 +1097,13 @@ const message = {
|
||||
approxWeightSize: 'Aprox. {0} GB',
|
||||
services: 'Servicios de modelos',
|
||||
addInstance: 'Añadir instancia',
|
||||
addService: 'Añadir servicio de modelo',
|
||||
modelScopeEndpointHelper: 'Para buscar y descargar modelos de ModelScope. Usa la URL oficial por defecto.',
|
||||
modelTokenHelper: 'Opcional. Use un token con permisos para acceder a modelos privados o restringidos.',
|
||||
modelDirHelper: 'Directorio de descarga y listado de modelos locales.',
|
||||
featuredModelsHelper:
|
||||
'Catálogo oficial de modelos destacados de 1Panel. Actualícelo manualmente o active la sincronización automática cada 24 horas. Solo se actualiza el catálogo, sin descargar modelos.',
|
||||
addInstanceHelper: 'Cree una instancia de vLLM para servir los modelos descargados.',
|
||||
addService: 'Añadir',
|
||||
onlineModel: 'Modelos en línea',
|
||||
instanceDeployment: 'Despliegue por instancia',
|
||||
engines: 'Motores de inferencia locales',
|
||||
@@ -1096,11 +1125,11 @@ const message = {
|
||||
recipeArguments: 'Argumentos de inicio',
|
||||
recipeImportCommand: 'Importar comando',
|
||||
recipeImportPlaceholder:
|
||||
'Pegue aquí un comando de inicio en formato pip/uv o Docker. 1Panel lo analizará y completará la Recipe automáticamente.',
|
||||
'Pegue aquí un comando de inicio en formato pip/uv o docker. 1Panel lo analizará y completará el formulario automáticamente.',
|
||||
recipeVariablesNotSupported:
|
||||
'No se admiten referencias a variables en los comandos. Use valores concretos; configure las variables de entorno en su campo correspondiente.',
|
||||
recipeImportError:
|
||||
'No se puede convertir. Incluya un comando de inicio Docker o vllm serve con un modelo; pegue los comandos de instalación pip/uv junto con el comando de inicio.',
|
||||
'No se detectó un comando de inicio válido. Pegue un comando pip/uv o docker que incluya un modelo.',
|
||||
engineProvider: 'Motor / Proveedor',
|
||||
endpoint: 'Punto de conexión',
|
||||
cloudAccount: 'Cuenta en la nube',
|
||||
@@ -1111,7 +1140,8 @@ const message = {
|
||||
model: 'Modelo',
|
||||
localModel: 'Modelos locales',
|
||||
create_helper: 'Descargar "{0}"',
|
||||
ollama_doc: 'Puede visitar el sitio oficial de Ollama para buscar y encontrar más modelos.',
|
||||
ollama_doc:
|
||||
'Busque modelos en {link}. El modelo se descargará automáticamente al añadirlo. Asegúrese de que Ollama esté funcionando y de que haya suficiente espacio en disco.',
|
||||
container_conn_helper: 'Utilice esta dirección para el acceso o conexión entre contenedores',
|
||||
from_remote: 'Este modelo no fue descargado vía 1Panel, no hay registros de descarga relacionados.',
|
||||
no_logs: 'Los registros de descarga de este modelo han sido eliminados y no se pueden consultar.',
|
||||
@@ -1132,7 +1162,7 @@ const message = {
|
||||
'La dirección del contenedor es para contenedores de agentes; 127.0.0.1, IP del sistema o dirección personalizada es para AI Gateway o servicios externos.',
|
||||
containerAddress: 'Dirección del contenedor',
|
||||
customAddress: 'Dirección personalizada',
|
||||
downloader: 'Gestión de descargas',
|
||||
downloader: 'Descarga de modelos',
|
||||
modelDirectoryHelper:
|
||||
'La lista muestra de forma predeterminada los modelos descargados en el directorio configurado en Preparación de modelos > Configuración.',
|
||||
modelDirectoryPlaceholder: 'Buscar modelos o introducir una ruta completa',
|
||||
@@ -1143,8 +1173,7 @@ const message = {
|
||||
endpointLabel: 'Endpoint de {0}',
|
||||
acceleratedEndpointLabel: 'Endpoint de aceleración de {0}',
|
||||
tokenLabel: 'Token de {0}',
|
||||
hfEndpointHelper:
|
||||
'Configure un endpoint de aceleración cuando el acceso a HuggingFace sea inestable. La búsqueda, los detalles y las descargas lo utilizarán.',
|
||||
hfEndpointHelper: 'URL de espejo opcional para búsquedas, detalles y descargas de modelos de HuggingFace.',
|
||||
sortDefault: 'Orden predeterminado',
|
||||
sortMostParameters: 'Más parámetros',
|
||||
sortLeastParameters: 'Menos parámetros',
|
||||
@@ -5114,8 +5143,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'Por favor, ingresa el comando de inicio completo, por ejemplo: npm run start. Para comandos de inicio de PM2, por favor reemplaza con pm2-runtime, de lo contrario fallará al iniciar.',
|
||||
portError: 'No repitas el mismo puerto.',
|
||||
systemRestartHelper:
|
||||
'Descripción de estado: Interrupción - fallo al obtener estado debido a reinicio del sistema',
|
||||
javaScriptHelper:
|
||||
'Proporciona un comando de inicio completo. Ejemplo: "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'El directorio debe contener archivos .jar, se permiten subdirectorios',
|
||||
|
||||
@@ -1025,6 +1025,29 @@ const message = {
|
||||
validateImageAvailabilityHelper: 'پیش از ذخیره یک تصویر حداقلی تولید میشود و ممکن است هزینه داشته باشد',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'جستجو و دانلود مدلها',
|
||||
searchHelper:
|
||||
'مدلها را در ModelScope یا Hugging Face پیدا کنید، سپس در آمادهسازی مدل آنها را مستقر کنید یا یک Recipe بسازید.',
|
||||
modelScopeSearchHelper: 'دسترسی پایدار در سرزمین اصلی چین',
|
||||
huggingFaceSearchHelper: 'مجموعه گسترده مدلها',
|
||||
searchPlaceholder: 'نام مدل یا شناسه مخزن را وارد کنید، مانند Qwen/Qwen3-8B',
|
||||
popularSearches: 'جستجوهای محبوب',
|
||||
searchSort: 'مرتبسازی',
|
||||
onlyTokenizer: 'فقط توکنساز',
|
||||
downloadStatus: 'وضعیت دانلود',
|
||||
downloaded: 'دانلود شده',
|
||||
alreadyExists: 'از قبل موجود',
|
||||
downloadCompleted: 'دانلود تکمیل شد',
|
||||
localFilesMissing: 'فایلهای محلی یافت نشد',
|
||||
ollamaNameHelper:
|
||||
'نام کامل مدل را از کتابخانه Ollama وارد کنید. اگر برچسب مشخص نشود، latest استفاده میشود.',
|
||||
downloadHelper: 'برای یافتن و دانلود مدلها از ModelScope و Hugging Face روی «جستجو» کلیک کنید.',
|
||||
serviceHelper:
|
||||
'سرویسهای مدل از ابرهای عمومی، موتورهای استنتاج محلی و درگاههای هوش مصنوعی را برای استفاده عاملهای داخلی 1Panel و عاملهای خارجی مانند WorkBuddy متصل کنید.',
|
||||
gpuType: 'نوع GPU',
|
||||
vllmVersion: 'نسخه vLLM',
|
||||
vllmImage: 'ایمیج vLLM',
|
||||
servicePort: 'پورت سرویس',
|
||||
gpuAcceleration: 'شتابدهی GPU',
|
||||
gpuMode: 'انتخاب شتابدهنده',
|
||||
gpuAll: 'همه شتابدهندهها',
|
||||
@@ -1055,7 +1078,13 @@ const message = {
|
||||
approxWeightSize: 'حدود {0} گیگابایت',
|
||||
services: 'سرویسهای مدل',
|
||||
addInstance: 'افزودن نمونه',
|
||||
addService: 'افزودن سرویس مدل',
|
||||
modelScopeEndpointHelper: 'برای جستجو و دانلود مدلهای ModelScope؛ پیشفرض، نشانی رسمی است.',
|
||||
modelTokenHelper: 'اختیاری. برای مدلهای خصوصی یا محدود از توکن دارای مجوز دسترسی استفاده کنید.',
|
||||
modelDirHelper: 'پوشهٔ دانلود مدلها و منبع فهرست مدلهای محلی.',
|
||||
featuredModelsHelper:
|
||||
'فهرست رسمی مدلهای منتخب 1Panel. بهصورت دستی بهروز کنید یا همگامسازی خودکار هر ۲۴ ساعت را فعال کنید. فقط فهرست بهروز میشود و فایل مدلها دانلود نمیشود.',
|
||||
addInstanceHelper: 'برای ارائهٔ مدلهای دانلودشده، یک نمونهٔ vLLM ایجاد کنید.',
|
||||
addService: 'افزودن',
|
||||
onlineModel: 'مدلهای آنلاین',
|
||||
instanceDeployment: 'استقرار بر اساس نمونه',
|
||||
engines: 'موتورهای استنتاج محلی',
|
||||
@@ -1077,11 +1106,10 @@ const message = {
|
||||
recipeArguments: 'آرگومانهای راهاندازی',
|
||||
recipeImportCommand: 'وارد کردن فرمان',
|
||||
recipeImportPlaceholder:
|
||||
'فرمان اجرا را با قالب pip/uv یا Docker اینجا جایگذاری کنید تا 1Panel آن را بهطور خودکار تحلیل و Recipe را تکمیل کند.',
|
||||
'فرمان اجرا را با قالب pip/uv یا docker اینجا جایگذاری کنید تا 1Panel آن را بهطور خودکار تحلیل و فرم را تکمیل کند.',
|
||||
recipeVariablesNotSupported:
|
||||
'ارجاع به متغیرها در دستور پشتیبانی نمیشود. مقادیر مشخص وارد کنید؛ متغیرهای محیطی را در بخش مربوط به آنها تنظیم کنید.',
|
||||
recipeImportError:
|
||||
'تبدیل ممکن نیست. فرمان راهاندازی Docker یا vllm serve همراه با مدل را وارد کنید؛ فرمانهای نصب pip/uv را همراه با فرمان راهاندازی جایگذاری کنید.',
|
||||
recipeImportError: 'فرمان اجرای معتبری شناسایی نشد. یک فرمان pip/uv یا docker شامل مدل را جایگذاری کنید.',
|
||||
engineProvider: 'موتور / ارائهدهنده',
|
||||
endpoint: 'نقطه پایانی',
|
||||
cloudAccount: 'حساب ابری',
|
||||
@@ -1092,7 +1120,8 @@ const message = {
|
||||
model: 'مدلها',
|
||||
localModel: 'مدلهای محلی',
|
||||
create_helper: 'دریافت "{0}"',
|
||||
ollama_doc: 'میتوانید از وبسایت رسمی Ollama دیدن کنید و مدلهای بیشتری را جستجو کنید.',
|
||||
ollama_doc:
|
||||
'مدلها را در {link} بیابید. مدل پس از افزودن بهطور خودکار دانلود میشود. مطمئن شوید سرویس Ollama در حال اجرا است و فضای دیسک کافی وجود دارد.',
|
||||
container_conn_helper: 'از این آدرس برای دسترسی بین کانتینرها یا اتصال استفاده کنید',
|
||||
from_remote: 'این مدل از طریق 1Panel دانلود نشده است، لاگ مربوط به دریافت وجود ندارد.',
|
||||
no_logs: 'لاگ دریافت این مدل حذف شده است و قابل مشاهده نیست.',
|
||||
@@ -1112,7 +1141,7 @@ const message = {
|
||||
'آدرس کانتینر برای کانتینرهای عامل است؛ 127.0.0.1، IP سیستم یا آدرس سفارشی برای دروازه AI یا خدمات خارجی است.',
|
||||
containerAddress: 'آدرس کانتینر',
|
||||
customAddress: 'آدرس سفارشی',
|
||||
downloader: 'مدیریت دانلودها',
|
||||
downloader: 'دانلود مدل',
|
||||
modelDirectoryHelper:
|
||||
'فهرست مدلها بهطور پیشفرض مدلهای دانلودشده در پوشه تنظیمشده در «آمادهسازی مدل > تنظیمات» را نمایش میدهد.',
|
||||
modelDirectoryPlaceholder: 'جستجوی مدل یا وارد کردن مسیر کامل',
|
||||
@@ -1123,8 +1152,7 @@ const message = {
|
||||
endpointLabel: 'نقطه پایانی {0}',
|
||||
acceleratedEndpointLabel: 'نقطه پایانی شتابدهنده {0}',
|
||||
tokenLabel: 'توکن {0}',
|
||||
hfEndpointHelper:
|
||||
'هنگامی که دسترسی به HuggingFace ناپایدار است، یک نقطه پایانی شتابدهنده پیکربندی کنید. جستجو، جزئیات و دانلود از آن استفاده خواهند کرد.',
|
||||
hfEndpointHelper: 'نشانی آینهٔ اختیاری برای جستجو، دریافت جزئیات و دانلود مدلهای HuggingFace.',
|
||||
sortDefault: 'مرتبسازی پیشفرض',
|
||||
sortMostParameters: 'بیشترین پارامتر',
|
||||
sortLeastParameters: 'کمترین پارامتر',
|
||||
@@ -5007,7 +5035,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'دستور راهاندازی کامل را وارد کنید، مثلاً: npm run start. برای دستورات راهاندازی PM2، لطفاً با pm2-runtime جایگزین کنید، در غیر این صورت راهاندازی ناموفق خواهد بود.',
|
||||
portError: 'پورت تکراری نباشد.',
|
||||
systemRestartHelper: 'توضیح وضعیت: وقفه - به دلیل راهاندازی مجدد سیستم، وضعیت قابل دریافت نیست',
|
||||
javaScriptHelper: 'یک دستور راهاندازی کامل ارائه دهید. مثلاً "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'دایرکتوری باید شامل فایلهای jar باشد، زیردایرکتوریها نیز مجاز هستند',
|
||||
goHelper: 'یک دستور راهاندازی کامل ارائه دهید. مثلاً "go run main.go" یا "./main".',
|
||||
|
||||
@@ -1029,6 +1029,30 @@ const message = {
|
||||
validateImageAvailabilityHelper: '保存前に最小画像を1枚生成するため、料金が発生する場合があります',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'モデルを検索してダウンロード',
|
||||
searchHelper:
|
||||
'ModelScope または Hugging Face でモデルを検索し、ダウンロード後にモデル準備でデプロイまたは Recipe を作成できます。',
|
||||
modelScopeSearchHelper: '中国本土から安定したアクセス',
|
||||
huggingFaceSearchHelper: '豊富なモデル',
|
||||
searchPlaceholder: 'モデル名またはリポジトリ ID を入力(例:Qwen/Qwen3-8B)',
|
||||
popularSearches: '人気の検索',
|
||||
searchSort: '並び順',
|
||||
onlyTokenizer: 'トークナイザーのみ',
|
||||
downloadStatus: 'ダウンロード状態',
|
||||
downloaded: 'ダウンロード済み',
|
||||
alreadyExists: '既存',
|
||||
downloadCompleted: 'ダウンロード完了',
|
||||
localFilesMissing: 'ローカルファイルが見つかりません',
|
||||
ollamaNameHelper:
|
||||
'Ollama ライブラリの完全なモデル名を入力してください。タグを省略すると latest が使用されます。',
|
||||
downloadHelper:
|
||||
'「検索」をクリックすると、ModelScope や Hugging Face のモデルを検索してダウンロードできます。',
|
||||
serviceHelper:
|
||||
'パブリッククラウド、ローカル推論エンジン、AI ゲートウェイなどのモデルサービスを統合し、1Panel 内蔵エージェントや WorkBuddy などの外部エージェントから利用できます。',
|
||||
gpuType: 'GPU タイプ',
|
||||
vllmVersion: 'vLLM バージョン',
|
||||
vllmImage: 'vLLM イメージ',
|
||||
servicePort: 'サービスポート',
|
||||
gpuAcceleration: 'GPU アクセラレーション',
|
||||
gpuMode: 'アクセラレーターの選択',
|
||||
gpuAll: 'すべてのアクセラレーター',
|
||||
@@ -1059,7 +1083,13 @@ const message = {
|
||||
approxWeightSize: '約 {0} GB',
|
||||
services: 'モデルサービス',
|
||||
addInstance: 'インスタンスを追加',
|
||||
addService: 'モデルサービスを追加',
|
||||
modelScopeEndpointHelper: 'ModelScope モデルの検索とダウンロードに使用します。既定は公式 URL です。',
|
||||
modelTokenHelper: '任意。非公開・制限付きモデルにはアクセス権のあるトークンが必要です。',
|
||||
modelDirHelper: 'モデルの保存先とローカルモデル一覧の読み込み先です。',
|
||||
featuredModelsHelper:
|
||||
'1Panel 公式のおすすめモデル一覧です。手動更新または 24 時間ごとの自動同期が可能です。同期は一覧のみを更新し、モデルファイルはダウンロードしません。',
|
||||
addInstanceHelper: 'vLLM インスタンスを作成し、ダウンロード済みモデルをモデルサービスとして公開します。',
|
||||
addService: '追加',
|
||||
onlineModel: 'オンラインモデル',
|
||||
instanceDeployment: 'インスタンス単位でデプロイ',
|
||||
engines: 'ローカル推論エンジン',
|
||||
@@ -1081,11 +1111,11 @@ const message = {
|
||||
recipeArguments: '起動引数',
|
||||
recipeImportCommand: 'コマンドをインポート',
|
||||
recipeImportPlaceholder:
|
||||
'ここに pip/uv または Docker 形式の起動コマンドを貼り付けると、1Panel が自動的に解析し、Recipe に入力します。',
|
||||
'ここに pip/uv または docker 形式の起動コマンドを貼り付けると、1Panel が自動的に解析し、フォームに入力します。',
|
||||
recipeVariablesNotSupported:
|
||||
'コマンド内の変数参照はサポートされていません。具体的な値を入力し、環境変数は環境変数欄で設定してください。',
|
||||
recipeImportError:
|
||||
'変換できません。モデルを含む Docker または vllm serve の起動コマンドを入力してください。pip/uv のインストールコマンドは起動コマンドと一緒に貼り付けてください。',
|
||||
'有効な起動コマンドが見つかりません。モデルを含む pip/uv または docker コマンドを貼り付けてください。',
|
||||
engineProvider: 'エンジン / プロバイダー',
|
||||
endpoint: 'エンドポイント',
|
||||
cloudAccount: 'クラウドアカウント',
|
||||
@@ -1096,7 +1126,8 @@ const message = {
|
||||
model: 'モデル',
|
||||
localModel: 'ローカルモデル',
|
||||
create_helper: 'を取得 "{0}"',
|
||||
ollama_doc: 'Ollama の公式ウェブサイトを訪れて、さらに多くのモデルを検索して見つけることができます。',
|
||||
ollama_doc:
|
||||
'{link} でモデルを検索できます。追加後、モデルは自動的に取得されます。Ollama が正常に動作し、十分なディスク容量があることを確認してください。',
|
||||
container_conn_helper: 'コンテナ間のアクセスまたは接続にこのアドレスを使用',
|
||||
from_remote: 'このモデルは1Panelを介してダウンロードされておらず、関連するプルログはありません。',
|
||||
no_logs: 'このモデルのプルログは削除されており、関連するログを表示できません。',
|
||||
@@ -1117,7 +1148,7 @@ const message = {
|
||||
'コンテナアドレスはエージェントコンテナ向けです。127.0.0.1、システム IP、カスタムアドレスは AI Gateway または外部サービス向けです。',
|
||||
containerAddress: 'コンテナアドレス',
|
||||
customAddress: 'カスタムアドレス',
|
||||
downloader: 'ダウンロード管理',
|
||||
downloader: 'モデルのダウンロード',
|
||||
modelDirectoryHelper:
|
||||
'モデル一覧には、デフォルトで「モデル準備 > 設定」で指定したモデルディレクトリにダウンロード済みのモデルが表示されます。',
|
||||
modelDirectoryPlaceholder: 'モデルを検索するかフルパスを入力',
|
||||
@@ -1128,8 +1159,7 @@ const message = {
|
||||
endpointLabel: '{0} エンドポイント',
|
||||
acceleratedEndpointLabel: '{0} アクセラレーションエンドポイント',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper:
|
||||
'HuggingFace へのアクセスが不安定な場合はアクセラレーションエンドポイントを設定してください。検索、詳細、ダウンロードで使用されます。',
|
||||
hfEndpointHelper: '任意。HuggingFace モデルの検索・詳細取得・ダウンロード用のミラー URL です。',
|
||||
sortDefault: '標準の並び順',
|
||||
sortMostParameters: 'パラメータ数が多い順',
|
||||
sortLeastParameters: 'パラメータ数が少ない順',
|
||||
@@ -5027,7 +5057,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'完全な起動コマンドを入力してください。例:npm run start。PM2の起動コマンドはpm2-runtimeに置き換えてください。そうしないと起動に失敗します。',
|
||||
portError: '同じポートを繰り返さないでください。',
|
||||
systemRestartHelper: 'ステータスの説明:中断 - システムの再起動によりステータスの取得が失敗しました',
|
||||
javaScriptHelper: '完全な起動コマンドを提供します。たとえば、「Java -Jar Halo.Jar -XMX1024M -XMS256M」。',
|
||||
javaDirHelper: 'ディレクトリにはjarファイルが含まれている必要があり、サブディレクトリも受け入れられます',
|
||||
goHelper: '完全な起動コマンドを提供します。たとえば、「Go Run Main.go」または「./Main」。',
|
||||
|
||||
@@ -1019,6 +1019,29 @@ const message = {
|
||||
validateImageAvailabilityHelper: '저장 전에 최소 이미지 한 장을 생성하며 비용이 발생할 수 있습니다',
|
||||
},
|
||||
model: {
|
||||
searchTitle: '모델 검색 및 다운로드',
|
||||
searchHelper:
|
||||
'ModelScope 또는 Hugging Face에서 모델을 찾아 다운로드한 후 모델 준비에서 배포하거나 Recipe를 만들 수 있습니다.',
|
||||
modelScopeSearchHelper: '중국 본토에서 안정적인 접속',
|
||||
huggingFaceSearchHelper: '풍부한 모델 컬렉션',
|
||||
searchPlaceholder: '모델 이름 또는 저장소 ID 입력, 예: Qwen/Qwen3-8B',
|
||||
popularSearches: '인기 검색어',
|
||||
searchSort: '정렬',
|
||||
onlyTokenizer: '토크나이저만 다운로드',
|
||||
downloadStatus: '다운로드 상태',
|
||||
downloaded: '다운로드됨',
|
||||
alreadyExists: '이미 존재함',
|
||||
downloadCompleted: '다운로드 완료',
|
||||
localFilesMissing: '로컬 파일을 찾을 수 없습니다',
|
||||
ollamaNameHelper: 'Ollama 라이브러리의 전체 모델 이름을 입력하세요. 태그를 생략하면 latest가 사용됩니다.',
|
||||
downloadHelper:
|
||||
'“검색” 버튼을 클릭하여 ModelScope 및 Hugging Face의 모델을 검색하고 다운로드할 수 있습니다.',
|
||||
serviceHelper:
|
||||
'퍼블릭 클라우드, 로컬 추론 엔진, AI 게이트웨이 등의 모델 서비스를 통합하여 1Panel 내장 에이전트와 WorkBuddy 같은 외부 에이전트에서 사용할 수 있습니다.',
|
||||
gpuType: 'GPU 유형',
|
||||
vllmVersion: 'vLLM 버전',
|
||||
vllmImage: 'vLLM 이미지',
|
||||
servicePort: '서비스 포트',
|
||||
gpuAcceleration: 'GPU 가속',
|
||||
gpuMode: '가속기 선택',
|
||||
gpuAll: '모든 가속기',
|
||||
@@ -1049,7 +1072,13 @@ const message = {
|
||||
approxWeightSize: '약 {0} GB',
|
||||
services: '모델 서비스',
|
||||
addInstance: '인스턴스 추가',
|
||||
addService: '모델 서비스 추가',
|
||||
modelScopeEndpointHelper: 'ModelScope 모델 검색 및 다운로드에 사용하며, 기본값은 공식 URL입니다.',
|
||||
modelTokenHelper: '선택 사항. 비공개 또는 제한된 모델에는 접근 권한이 있는 토큰이 필요합니다.',
|
||||
modelDirHelper: '모델 다운로드 저장 경로이자 로컬 모델 목록을 읽는 경로입니다.',
|
||||
featuredModelsHelper:
|
||||
'1Panel 공식 추천 모델 목록입니다. 수동으로 새로 고치거나 24시간마다 자동 동기화를 설정할 수 있습니다. 목록만 갱신하며 모델 파일은 다운로드하지 않습니다.',
|
||||
addInstanceHelper: 'vLLM 인스턴스를 생성하여 다운로드한 모델을 모델 서비스로 배포합니다.',
|
||||
addService: '추가',
|
||||
onlineModel: '온라인 모델',
|
||||
instanceDeployment: '인스턴스별 배포',
|
||||
engines: '로컬 추론 엔진',
|
||||
@@ -1071,11 +1100,11 @@ const message = {
|
||||
recipeArguments: '시작 인수',
|
||||
recipeImportCommand: '명령 가져오기',
|
||||
recipeImportPlaceholder:
|
||||
'여기에 pip/uv 또는 Docker 형식의 실행 명령을 붙여넣으면 1Panel이 자동으로 분석하여 Recipe를 채웁니다.',
|
||||
'여기에 pip/uv 또는 docker 형식의 실행 명령을 붙여넣으면 1Panel이 자동으로 분석하여 양식을 채웁니다.',
|
||||
recipeVariablesNotSupported:
|
||||
'명령에서 변수 참조는 지원되지 않습니다. 구체적인 값을 입력하고 환경 변수는 환경 변수 필드에서 설정하세요.',
|
||||
recipeImportError:
|
||||
'변환할 수 없습니다. 모델이 포함된 Docker 또는 vllm serve 시작 명령을 입력하세요. pip/uv 설치 명령은 시작 명령과 함께 붙여넣으세요.',
|
||||
'유효한 실행 명령을 찾지 못했습니다. 모델이 포함된 pip/uv 또는 docker 명령을 붙여넣으세요.',
|
||||
engineProvider: '엔진 / 공급자',
|
||||
endpoint: '엔드포인트',
|
||||
cloudAccount: '클라우드 계정',
|
||||
@@ -1086,7 +1115,8 @@ const message = {
|
||||
model: '모델',
|
||||
localModel: '로컬 모델',
|
||||
create_helper: '가져오기 "{0}"',
|
||||
ollama_doc: 'Ollama 공식 웹사이트를 방문하여 더 많은 모델을 검색하고 찾을 수 있습니다.',
|
||||
ollama_doc:
|
||||
'{link}에서 모델을 검색하세요. 추가 후 모델을 자동으로 가져옵니다. Ollama 서비스가 정상적으로 실행 중이고 디스크 공간이 충분한지 확인하세요.',
|
||||
container_conn_helper: '컨테이너 간 접근 또는 연결에 이 주소를 사용',
|
||||
from_remote: '이 모델은 1Panel을 통해 다운로드되지 않았으며 관련 풀 로그가 없습니다.',
|
||||
no_logs: '이 모델의 풀 로그가 삭제되어 관련 로그를 볼 수 없습니다.',
|
||||
@@ -1106,7 +1136,7 @@ const message = {
|
||||
'컨테이너 주소는 에이전트 컨테이너 호출에 적합합니다. 127.0.0.1, 시스템 IP 또는 사용자 지정 주소는 AI Gateway 또는 외부 서비스 호출에 적합합니다.',
|
||||
containerAddress: '컨테이너 주소',
|
||||
customAddress: '사용자 지정 주소',
|
||||
downloader: '다운로드 관리',
|
||||
downloader: '모델 다운로드',
|
||||
modelDirectoryHelper:
|
||||
'모델 목록은 기본적으로 “모델 준비 > 설정”에서 구성한 모델 디렉터리에 다운로드된 모델을 표시합니다.',
|
||||
modelDirectoryPlaceholder: '모델 검색 또는 전체 경로 입력',
|
||||
@@ -1117,8 +1147,7 @@ const message = {
|
||||
endpointLabel: '{0} 엔드포인트',
|
||||
acceleratedEndpointLabel: '{0} 가속 엔드포인트',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper:
|
||||
'HuggingFace 접속이 불안정할 때 가속 엔드포인트를 설정하세요. 검색, 상세 정보, 다운로드에 사용됩니다.',
|
||||
hfEndpointHelper: '선택 사항. HuggingFace 모델 검색, 상세 정보 조회 및 다운로드용 미러 URL입니다.',
|
||||
sortDefault: '기본 정렬',
|
||||
sortMostParameters: '매개변수 많은 순',
|
||||
sortLeastParameters: '매개변수 적은 순',
|
||||
@@ -4937,7 +4966,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'전체 시작 명령어를 입력해 주세요. 예: npm run start. PM2 시작 명령어는 pm2-runtime로 변경해 주세요. 그렇지 않으면 시작에 실패합니다.',
|
||||
portError: '포트를 중복 사용하지 마세요.',
|
||||
systemRestartHelper: '상태 설명: 중단 - 시스템 재시작으로 인해 상태 가져오기가 실패했습니다.',
|
||||
javaScriptHelper: '전체 시작 명령을 제공하세요. 예: "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: '디렉터리는 jar 파일을 포함해야 하며, 하위 디렉터리도 허용됩니다.',
|
||||
goHelper: '전체 시작 명령을 제공하세요. 예: "go run main.go" 또는 "./main".',
|
||||
|
||||
@@ -1016,6 +1016,27 @@ const message = {
|
||||
validateImageAvailabilityHelper: 'ສ້າງຮູບຂະໜາດນ້ອຍໜຶ່ງຮູບກ່ອນບັນທຶກ ແລະ ອາດມີຄ່າໃຊ້ຈ່າຍ',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'ຄົ້ນຫາ ແລະ ດາວໂຫຼດໂມເດວ',
|
||||
searchHelper: 'ຄົ້ນຫາໂມເດວໃນ ModelScope ຫຼື Hugging Face ແລ້ວນຳໃຊ້ ຫຼື ສ້າງ Recipe ໃນການກະກຽມໂມເດວ.',
|
||||
modelScopeSearchHelper: 'ເຂົ້າເຖິງໄດ້ສະຖຽນໃນຈີນແຜ່ນດິນໃຫຍ່',
|
||||
huggingFaceSearchHelper: 'ມີໂມເດວໃຫ້ເລືອກຫຼາກຫຼາຍ',
|
||||
searchPlaceholder: 'ປ້ອນຊື່ໂມເດວ ຫຼື ID ຄັງ, ເຊັ່ນ Qwen/Qwen3-8B',
|
||||
popularSearches: 'ການຄົ້ນຫາຍອດນິຍົມ',
|
||||
searchSort: 'ຈັດລຽງ',
|
||||
onlyTokenizer: 'ດາວໂຫຼດສະເພາະຕົວແບ່ງໂທເຄັນ',
|
||||
downloadStatus: 'ສະຖານະດາວໂຫຼດ',
|
||||
downloaded: 'ດາວໂຫຼດແລ້ວ',
|
||||
alreadyExists: 'ມີຢູ່ແລ້ວ',
|
||||
downloadCompleted: 'ດາວໂຫຼດສຳເລັດ',
|
||||
localFilesMissing: 'ບໍ່ພົບໄຟລ໌ພາຍໃນ',
|
||||
ollamaNameHelper: 'ກະລຸນາໃສ່ຊື່ໂມເດວເຕັມຈາກຄັງ Ollama. ຖ້າບໍ່ລະບຸແທັກ ຈະໃຊ້ latest.',
|
||||
downloadHelper: 'ຄລິກ “ຄົ້ນຫາ” ເພື່ອຄົ້ນຫາ ແລະ ດາວໂຫຼດໂມເດວຈາກ ModelScope ແລະ Hugging Face.',
|
||||
serviceHelper:
|
||||
'ເຊື່ອມຕໍ່ບໍລິການໂມເດວຈາກຄລາວສາທາລະນະ, ເຄື່ອງຈັກອະນຸມານພາຍໃນ ແລະ ເກດເວ AI ເພື່ອໃຫ້ຕົວແທນໃນ 1Panel ແລະ ຕົວແທນພາຍນອກເຊັ່ນ WorkBuddy ໃຊ້ງານ.',
|
||||
gpuType: 'ປະເພດ GPU',
|
||||
vllmVersion: 'ເວີຊັນ vLLM',
|
||||
vllmImage: 'ອິມເມຈ vLLM',
|
||||
servicePort: 'ພອດບໍລິການ',
|
||||
gpuAcceleration: 'ການເລັ່ງ GPU',
|
||||
gpuMode: 'ເລືອກຕົວເລັ່ງ',
|
||||
gpuAll: 'ຕົວເລັ່ງທັງໝົດ',
|
||||
@@ -1046,7 +1067,13 @@ const message = {
|
||||
approxWeightSize: 'ປະມານ {0} GB',
|
||||
services: 'ບໍລິການໂມເດວ',
|
||||
addInstance: 'ເພີ່ມອິນສະແຕນ',
|
||||
addService: 'ເພີ່ມບໍລິການໂມເດວ',
|
||||
modelScopeEndpointHelper: 'ໃຊ້ຄົ້ນຫາ ແລະ ດາວໂຫຼດໂມເດວ ModelScope. ຄ່າເລີ່ມຕົ້ນແມ່ນ URL ທາງການ.',
|
||||
modelTokenHelper: 'ບໍ່ບັງຄັບ. ໂມເດວສ່ວນຕົວ ຫຼື ທີ່ຈຳກັດຕ້ອງໃຊ້ Token ທີ່ມີສິດເຂົ້າເຖິງ.',
|
||||
modelDirHelper: 'ໂຟນເດີດາວໂຫຼດໂມເດວ ແລະ ແຫຼ່ງລາຍການໂມເດວພາຍໃນເຄື່ອງ.',
|
||||
featuredModelsHelper:
|
||||
'ລາຍການໂມເດວແນະນຳທາງການຂອງ 1Panel. ສາມາດໂຫຼດຄືນດ້ວຍຕົນເອງ ຫຼື ເປີດການຊິງຄ໌ອັດຕະໂນມັດທຸກ 24 ຊົ່ວໂມງ. ອັບເດດສະເພາະລາຍການ ໂດຍບໍ່ດາວໂຫຼດໄຟລ໌ໂມເດວ.',
|
||||
addInstanceHelper: 'ສ້າງອິນສະແຕນ vLLM ເພື່ອໃຫ້ບໍລິການໂມເດວທີ່ດາວໂຫຼດແລ້ວ.',
|
||||
addService: 'ເພີ່ມ',
|
||||
onlineModel: 'ໂມເດວອອນລາຍ',
|
||||
instanceDeployment: 'ນຳໃຊ້ຕາມອິນສະແຕນ',
|
||||
engines: 'ເຄື່ອງຈັກອະນຸມານພາຍໃນ',
|
||||
@@ -1068,11 +1095,10 @@ const message = {
|
||||
recipeArguments: 'ພາລາມິເຕີເລີ່ມຕົ້ນ',
|
||||
recipeImportCommand: 'ນຳເຂົ້າຄຳສັ່ງ',
|
||||
recipeImportPlaceholder:
|
||||
'ວາງຄຳສັ່ງເລີ່ມຕົ້ນໃນຮູບແບບ pip/uv ຫຼື Docker ທີ່ນີ້. 1Panel ຈະວິເຄາະແລະຕື່ມ Recipe ອັດຕະໂນມັດ.',
|
||||
'ວາງຄຳສັ່ງເລີ່ມຕົ້ນໃນຮູບແບບ pip/uv ຫຼື docker ທີ່ນີ້. 1Panel ຈະວິເຄາະ ແລະ ຕື່ມແບບຟອມອັດຕະໂນມັດ.',
|
||||
recipeVariablesNotSupported:
|
||||
'ຄຳສັ່ງບໍ່ຮອງຮັບການອ້າງອີງຕົວແປ. ກະລຸນາປ້ອນຄ່າໂດຍກົງ ແລະຕັ້ງຄ່າຕົວແປສະພາບແວດລ້ອມໃນຊ່ອງທີ່ກ່ຽວຂ້ອງ.',
|
||||
recipeImportError:
|
||||
'ບໍ່ສາມາດແປງໄດ້. ກະລຸນາໃສ່ຄຳສັ່ງເລີ່ມຕົ້ນ Docker ຫຼື vllm serve ທີ່ມີໂມເດວ; ວາງຄຳສັ່ງຕິດຕັ້ງ pip/uv ພ້ອມກັບຄຳສັ່ງເລີ່ມຕົ້ນ.',
|
||||
recipeImportError: 'ບໍ່ພົບຄຳສັ່ງເລີ່ມຕົ້ນທີ່ຖືກຕ້ອງ. ກະລຸນາວາງຄຳສັ່ງ pip/uv ຫຼື docker ທີ່ມີໂມເດວ.',
|
||||
engineProvider: 'ເຄື່ອງຈັກ / ຜູ້ໃຫ້ບໍລິການ',
|
||||
endpoint: 'ຈຸດເຊື່ອມຕໍ່',
|
||||
cloudAccount: 'ບັນຊີຄລາວ',
|
||||
@@ -1083,7 +1109,8 @@ const message = {
|
||||
model: 'ໂມເດວ',
|
||||
localModel: 'ໂມເດວໃນເຄື່ອງ',
|
||||
create_helper: 'ດຶງ (Pull) "{0}"',
|
||||
ollama_doc: 'ທ່ານສາມາດຢ້ຽມຊົມເວັບໄຊທ໌ທາງການຂອງ Ollama ເພື່ອຄົ້ນຫາໂມເດວເພີ່ມເຕີມ.',
|
||||
ollama_doc:
|
||||
'ຄົ້ນຫາໂມເດວທີ່ {link}. ລະບົບຈະດາວໂຫຼດໂມເດວອັດຕະໂນມັດຫຼັງຈາກເພີ່ມ. ກະລຸນາກວດສອບວ່າ Ollama ເຮັດວຽກປົກກະຕິ ແລະ ມີພື້ນທີ່ດິສກ໌ພຽງພໍ.',
|
||||
container_conn_helper: 'ໃຊ້ທີ່ຢູ່ນີ້ສຳລັບການເຂົ້າເຖິງ ຫຼື ເຊື່ອມຕໍ່ລະຫວ່າງຄອນເທນເນີ',
|
||||
from_remote: 'ໂມເດວນີ້ບໍ່ໄດ້ດາວໂຫຼດຜ່ານ 1Panel, ບໍ່ມີລັອກການດຶງຂໍ້ມູນທີ່ກ່ຽວຂ້ອງ.',
|
||||
no_logs: 'ລັອກການດຶງຂໍ້ມູນຂອງໂມເດວນີ້ຖືກລຶບແລ້ວ ແລະ ບໍ່ສາມາດເບິ່ງໄດ້.',
|
||||
@@ -1103,7 +1130,7 @@ const message = {
|
||||
'ທີ່ຢູ່ຄອນເທນເນີແມ່ນສຳລັບຄອນເທນເນີຕົວແທນ; 127.0.0.1, IP ລະບົບ, ຫຼື ທີ່ຢູ່ກຳນົດເອງແມ່ນສຳລັບ AI Gateway ຫຼື ບໍລິການພາຍນອກ.',
|
||||
containerAddress: 'ທີ່ຢູ່ຄອນເທນເນີ',
|
||||
customAddress: 'ທີ່ຢູ່ກຳນົດເອງ',
|
||||
downloader: 'ຈັດການການດາວໂຫຼດ',
|
||||
downloader: 'ດາວໂຫຼດໂມເດວ',
|
||||
modelDirectoryHelper:
|
||||
'ໂດຍຄ່າເລີ່ມຕົ້ນ ລາຍຊື່ໂມເດວຈະສະແດງໂມເດວທີ່ດາວໂຫຼດໄວ້ໃນໄດເຣັກທໍຣີທີ່ກຳນົດໃນ “ການກະກຽມໂມເດວ > ການຕັ້ງຄ່າ”.',
|
||||
modelDirectoryPlaceholder: 'ຄົ້ນຫາໂມເດວ ຫຼື ປ້ອນເສັ້ນທາງເຕັມ',
|
||||
@@ -1114,8 +1141,7 @@ const message = {
|
||||
endpointLabel: 'ຈຸດເຊື່ອມຕໍ່ (Endpoint) {0}',
|
||||
acceleratedEndpointLabel: 'ຈຸດເຊື່ອມຕໍ່ເລັ່ງຄວາມໄວ {0}',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper:
|
||||
'ຕັ້ງຄ່າຈຸດເຊື່ອມຕໍ່ເລັ່ງຄວາມໄວເມື່ອການເຂົ້າເຖິງ HuggingFace ບໍ່ຄົງທີ່. ການຄົ້ນຫາ, ລາຍລະອຽດ ແລະ ການດາວໂຫຼດຈະໃຊ້ທີ່ຢູ່ນີ້.',
|
||||
hfEndpointHelper: 'URL ມິເຣີທາງເລືອກສຳລັບຄົ້ນຫາ, ເບິ່ງລາຍລະອຽດ ແລະ ດາວໂຫຼດໂມເດວ HuggingFace.',
|
||||
sortDefault: 'ການຈັດລຽງເລີ່ມຕົ້ນ',
|
||||
sortMostParameters: 'ພາລາມິເຕີຫຼາຍທີ່ສຸດ',
|
||||
sortLeastParameters: 'ພາລາມິເຕີໜ້ອຍທີ່ສຸດ',
|
||||
@@ -4895,7 +4921,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'ປ້ອນຄຳສັ່ງເລີ່ມຕົ້ນທີ່ສົມບູນ ຕົວຢ່າງ: npm run start. ສຳລັບຄຳສັ່ງ PM2, ໃຫ້ປ່ຽນເປັນ pm2-runtime.',
|
||||
portError: 'ຫ້າມໃຊ້ພອດຊ້ຳກັນ.',
|
||||
systemRestartHelper: 'ລາຍລະອຽດ: ຖືກຂັດຈັງຫວະ - ບໍ່ສາມາດດຶງສະຖານະໄດ້ເນື່ອງຈາກລະບົບເລີ່ມຕົ້ນໃໝ່',
|
||||
javaScriptHelper: 'ປ້ອນຄຳສັ່ງເລີ່ມຕົ້ນທີ່ສົມບູນ ຕົວຢ່າງ: "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'ໂຟນເດີຕ້ອງມີໄຟລ໌ jar, ໂຟນເດີ່ຍ່ອຍກໍສາມາດໃຊ້ໄດ້',
|
||||
goHelper: 'ປ້ອນຄຳສັ່ງເລີ່ມຕົ້ນທີ່ສົມບູນ ຕົວຢ່າງ: "go run main.go" ຫຼື "./main".',
|
||||
|
||||
@@ -1052,6 +1052,29 @@ const message = {
|
||||
validateImageAvailabilityHelper: 'Menjana satu imej minimum sebelum menyimpan dan mungkin dikenakan caj',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'Cari dan muat turun model',
|
||||
searchHelper:
|
||||
'Cari model di ModelScope atau Hugging Face, kemudian gunakan model atau cipta Recipe dalam Persediaan Model.',
|
||||
modelScopeSearchHelper: 'Akses stabil di tanah besar China',
|
||||
huggingFaceSearchHelper: 'Koleksi model yang luas',
|
||||
searchPlaceholder: 'Masukkan nama model atau ID repositori, cth. Qwen/Qwen3-8B',
|
||||
popularSearches: 'Carian popular',
|
||||
searchSort: 'Susun mengikut',
|
||||
onlyTokenizer: 'Pentoken sahaja',
|
||||
downloadStatus: 'Status muat turun',
|
||||
downloaded: 'Telah dimuat turun',
|
||||
alreadyExists: 'Sudah wujud',
|
||||
downloadCompleted: 'Muat turun selesai',
|
||||
localFilesMissing: 'Fail setempat tidak ditemui',
|
||||
ollamaNameHelper:
|
||||
'Masukkan nama model penuh daripada pustaka Ollama. Jika tag tidak dinyatakan, latest akan digunakan.',
|
||||
downloadHelper: 'Klik “Cari” untuk mencari dan memuat turun model daripada ModelScope dan Hugging Face.',
|
||||
serviceHelper:
|
||||
'Sambungkan perkhidmatan model daripada awan awam, enjin inferens setempat dan gerbang AI untuk digunakan oleh ejen terbina dalam 1Panel serta ejen luaran seperti WorkBuddy.',
|
||||
gpuType: 'Jenis GPU',
|
||||
vllmVersion: 'Versi vLLM',
|
||||
vllmImage: 'Imej vLLM',
|
||||
servicePort: 'Port perkhidmatan',
|
||||
gpuAcceleration: 'Pecutan GPU',
|
||||
gpuMode: 'Pemilihan pemecut',
|
||||
gpuAll: 'Semua pemecut',
|
||||
@@ -1082,7 +1105,15 @@ const message = {
|
||||
approxWeightSize: 'Kira-kira {0} GB',
|
||||
services: 'Perkhidmatan model',
|
||||
addInstance: 'Tambah instans',
|
||||
addService: 'Tambah perkhidmatan model',
|
||||
modelScopeEndpointHelper:
|
||||
'Untuk mencari dan memuat turun model ModelScope. Menggunakan URL rasmi secara lalai.',
|
||||
modelTokenHelper: 'Pilihan. Gunakan token dengan kebenaran akses untuk model peribadi atau terhad.',
|
||||
modelDirHelper: 'Direktori muat turun model dan sumber senarai model setempat.',
|
||||
featuredModelsHelper:
|
||||
'Katalog model pilihan rasmi 1Panel. Muat semula secara manual atau aktifkan penyegerakan automatik setiap 24 jam. Hanya katalog dikemas kini, tanpa memuat turun fail model.',
|
||||
addInstanceHelper:
|
||||
'Cipta instans vLLM untuk menyediakan model yang dimuat turun sebagai perkhidmatan model.',
|
||||
addService: 'Tambah',
|
||||
onlineModel: 'Model dalam talian',
|
||||
instanceDeployment: 'Pengerahan mengikut instans',
|
||||
engines: 'Enjin inferens setempat',
|
||||
@@ -1104,11 +1135,11 @@ const message = {
|
||||
recipeArguments: 'Argumen pelancaran',
|
||||
recipeImportCommand: 'Import arahan',
|
||||
recipeImportPlaceholder:
|
||||
'Tampal arahan pelancaran dalam format pip/uv atau Docker di sini. 1Panel akan menghuraikan dan mengisi Recipe secara automatik.',
|
||||
'Tampal arahan pelancaran dalam format pip/uv atau docker di sini. 1Panel akan menghuraikan dan mengisi borang secara automatik.',
|
||||
recipeVariablesNotSupported:
|
||||
'Rujukan pemboleh ubah tidak disokong dalam arahan. Masukkan nilai khusus; tetapkan pemboleh ubah persekitaran dalam medan yang berkenaan.',
|
||||
recipeImportError:
|
||||
'Tidak dapat menukar. Sertakan arahan pelancaran Docker atau vllm serve dengan model; tampal arahan pemasangan pip/uv bersama arahan pelancaran.',
|
||||
'Tiada arahan pelancaran yang sah dikesan. Tampal arahan pip/uv atau docker yang mengandungi model.',
|
||||
engineProvider: 'Enjin / Pembekal',
|
||||
endpoint: 'Titik akhir',
|
||||
cloudAccount: 'Akaun awan',
|
||||
@@ -1119,7 +1150,8 @@ const message = {
|
||||
model: 'Model',
|
||||
localModel: 'Model Tempatan',
|
||||
create_helper: 'Tarik "{0}"',
|
||||
ollama_doc: 'Anda boleh melawat laman web rasmi Ollama untuk mencari dan menemui lebih banyak model.',
|
||||
ollama_doc:
|
||||
'Cari model di {link}. Model akan dimuat turun secara automatik selepas ditambah. Pastikan perkhidmatan Ollama berjalan dan ruang cakera mencukupi.',
|
||||
container_conn_helper: 'Gunakan alamat ini untuk akses atau sambungan antara kontena',
|
||||
from_remote: 'Model ini tidak dimuat turun melalui 1Panel; tiada log muat turun berkaitan.',
|
||||
no_logs: 'Log muat turun model ini telah dipadam dan tidak boleh dilihat.',
|
||||
@@ -1139,7 +1171,7 @@ const message = {
|
||||
'Alamat kontena sesuai untuk kontena agen; 127.0.0.1, IP sistem, atau alamat tersuai sesuai untuk AI Gateway atau perkhidmatan luaran.',
|
||||
containerAddress: 'Alamat kontena',
|
||||
customAddress: 'Alamat tersuai',
|
||||
downloader: 'Pengurusan muat turun',
|
||||
downloader: 'Muat turun model',
|
||||
modelDirectoryHelper:
|
||||
'Secara lalai, senarai model memaparkan model yang dimuat turun dalam direktori yang dikonfigurasi di Persediaan Model > Tetapan.',
|
||||
modelDirectoryPlaceholder: 'Cari model atau masukkan laluan penuh',
|
||||
@@ -1150,8 +1182,7 @@ const message = {
|
||||
endpointLabel: 'Endpoint {0}',
|
||||
acceleratedEndpointLabel: 'Titik akhir pecutan {0}',
|
||||
tokenLabel: 'Token {0}',
|
||||
hfEndpointHelper:
|
||||
'Konfigurasikan titik akhir pecutan apabila akses HuggingFace tidak stabil. Carian, butiran dan muat turun akan menggunakannya.',
|
||||
hfEndpointHelper: 'URL cermin pilihan untuk carian, butiran dan muat turun model HuggingFace.',
|
||||
sortDefault: 'Isihan lalai',
|
||||
sortMostParameters: 'Parameter terbanyak',
|
||||
sortLeastParameters: 'Parameter paling sedikit',
|
||||
@@ -5120,7 +5151,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'Sila masukkan arahan permulaan penuh, contoh: npm run start. Untuk arahan permulaan PM2, sila gantikan dengan pm2-runtime, jika tidak ia akan gagal bermula.',
|
||||
portError: 'Jangan ulangi port yang sama.',
|
||||
systemRestartHelper: 'Huraian status: Gangguan - status gagal diperoleh kerana sistem dimulakan semula',
|
||||
javaScriptHelper: 'Sediakan arahan permulaan penuh. Contohnya, "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'Direktori mesti mengandungi fail jar, subdirektori juga diterima',
|
||||
goHelper: 'Sediakan arahan permulaan penuh. Contohnya, "go run main.go" atau "./main".',
|
||||
|
||||
@@ -1047,6 +1047,29 @@ const message = {
|
||||
validateImageAvailabilityHelper: 'Gera uma imagem mínima antes de salvar e pode gerar custos',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'Pesquisar e baixar modelos',
|
||||
searchHelper:
|
||||
'Encontre modelos no ModelScope ou Hugging Face e depois implante-os ou crie uma Recipe em Preparação de modelos.',
|
||||
modelScopeSearchHelper: 'Acesso estável na China continental',
|
||||
huggingFaceSearchHelper: 'Ampla coleção de modelos',
|
||||
searchPlaceholder: 'Digite o nome ou ID do repositório, ex.: Qwen/Qwen3-8B',
|
||||
popularSearches: 'Buscas populares',
|
||||
searchSort: 'Ordenar por',
|
||||
onlyTokenizer: 'Somente tokenizador',
|
||||
downloadStatus: 'Status do download',
|
||||
downloaded: 'Baixado',
|
||||
alreadyExists: 'Já existe',
|
||||
downloadCompleted: 'Download concluído',
|
||||
localFilesMissing: 'Arquivos locais não encontrados',
|
||||
ollamaNameHelper:
|
||||
'Insira o nome completo do modelo da biblioteca do Ollama. Se nenhuma tag for especificada, será usada latest.',
|
||||
downloadHelper: 'Clique em “Pesquisar” para encontrar e baixar modelos do ModelScope e do Hugging Face.',
|
||||
serviceHelper:
|
||||
'Conecte serviços de modelos de nuvens públicas, mecanismos de inferência locais e gateways de IA para uso pelos agentes integrados do 1Panel e agentes externos, como o WorkBuddy.',
|
||||
gpuType: 'Tipo de GPU',
|
||||
vllmVersion: 'Versão do vLLM',
|
||||
vllmImage: 'Imagem do vLLM',
|
||||
servicePort: 'Porta do serviço',
|
||||
gpuAcceleration: 'Aceleração de GPU',
|
||||
gpuMode: 'Seleção de aceleradores',
|
||||
gpuAll: 'Todos os aceleradores',
|
||||
@@ -1078,7 +1101,13 @@ const message = {
|
||||
approxWeightSize: 'Aprox. {0} GB',
|
||||
services: 'Serviços de modelos',
|
||||
addInstance: 'Adicionar instância',
|
||||
addService: 'Adicionar serviço de modelo',
|
||||
modelScopeEndpointHelper: 'Para buscar e baixar modelos do ModelScope. Usa a URL oficial por padrão.',
|
||||
modelTokenHelper: 'Opcional. Use um token com permissão para acessar modelos privados ou restritos.',
|
||||
modelDirHelper: 'Diretório de download e listagem dos modelos locais.',
|
||||
featuredModelsHelper:
|
||||
'Catálogo oficial de modelos em destaque do 1Panel. Atualize manualmente ou ative a sincronização automática a cada 24 horas. Apenas o catálogo é atualizado, sem baixar modelos.',
|
||||
addInstanceHelper: 'Crie uma instância do vLLM para servir os modelos baixados.',
|
||||
addService: 'Adicionar',
|
||||
onlineModel: 'Modelos online',
|
||||
instanceDeployment: 'Implantação por instância',
|
||||
engines: 'Mecanismos de inferência locais',
|
||||
@@ -1100,11 +1129,11 @@ const message = {
|
||||
recipeArguments: 'Argumentos de inicialização',
|
||||
recipeImportCommand: 'Importar comando',
|
||||
recipeImportPlaceholder:
|
||||
'Cole um comando de inicialização no formato pip/uv ou Docker aqui. O 1Panel irá analisar e preencher a Recipe automaticamente.',
|
||||
'Cole um comando de inicialização no formato pip/uv ou docker aqui. O 1Panel irá analisar e preencher o formulário automaticamente.',
|
||||
recipeVariablesNotSupported:
|
||||
'Referências a variáveis não são aceitas nos comandos. Use valores explícitos; configure as variáveis de ambiente no campo correspondente.',
|
||||
recipeImportError:
|
||||
'Não foi possível converter. Inclua um comando de inicialização Docker ou vllm serve com um modelo; cole os comandos de instalação pip/uv junto com o comando de inicialização.',
|
||||
'Nenhum comando de inicialização válido foi detectado. Cole um comando pip/uv ou docker que inclua um modelo.',
|
||||
engineProvider: 'Mecanismo / Provedor',
|
||||
endpoint: 'Endpoint',
|
||||
cloudAccount: 'Conta na nuvem',
|
||||
@@ -1115,7 +1144,8 @@ const message = {
|
||||
model: 'Modelo',
|
||||
localModel: 'Modelos locais',
|
||||
create_helper: 'Puxar "{0}"',
|
||||
ollama_doc: 'Você pode visitar o site oficial da Ollama para pesquisar e encontrar mais modelos.',
|
||||
ollama_doc:
|
||||
'Busque modelos em {link}. O modelo será baixado automaticamente após ser adicionado. Verifique se o Ollama está em execução e se há espaço suficiente em disco.',
|
||||
container_conn_helper: 'Use este endereço para acesso ou conexão entre contêineres',
|
||||
from_remote: 'Este modelo não foi baixado pelo 1Panel; não há logs de download relacionados.',
|
||||
no_logs: 'Os logs de download deste modelo foram excluídos e não podem ser visualizados.',
|
||||
@@ -1135,7 +1165,7 @@ const message = {
|
||||
'Use o endereço do contêiner para agentes; 127.0.0.1, IP do sistema ou endereço personalizado para AI Gateway ou serviços externos.',
|
||||
containerAddress: 'Endereço do contêiner',
|
||||
customAddress: 'Endereço personalizado',
|
||||
downloader: 'Gerenciamento de downloads',
|
||||
downloader: 'Download de modelos',
|
||||
modelDirectoryHelper:
|
||||
'Por padrão, a lista exibe os modelos baixados no diretório configurado em Preparação de modelos > Configurações.',
|
||||
modelDirectoryPlaceholder: 'Buscar modelos ou inserir um caminho completo',
|
||||
@@ -1146,8 +1176,7 @@ const message = {
|
||||
endpointLabel: 'Endpoint do {0}',
|
||||
acceleratedEndpointLabel: 'Endpoint de aceleração do {0}',
|
||||
tokenLabel: 'Token do {0}',
|
||||
hfEndpointHelper:
|
||||
'Configure um endpoint de aceleração quando o acesso ao HuggingFace estiver instável. A pesquisa, os detalhes e os downloads usarão esse endereço.',
|
||||
hfEndpointHelper: 'URL de espelho opcional para buscas, detalhes e downloads de modelos do HuggingFace.',
|
||||
sortDefault: 'Ordenação padrão',
|
||||
sortMostParameters: 'Mais parâmetros',
|
||||
sortLeastParameters: 'Menos parâmetros',
|
||||
@@ -5145,8 +5174,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'Por favor, insira o comando de inicialização completo, por exemplo: npm run start. Para comandos de inicialização do PM2, substitua por pm2-runtime, caso contrário irá falhar ao iniciar.',
|
||||
portError: 'Evite repetir a mesma porta.',
|
||||
systemRestartHelper:
|
||||
'Descrição do status: Interrupção - falha ao adquirir status devido à reinicialização do sistema.',
|
||||
javaScriptHelper:
|
||||
'Forneça um comando completo de inicialização. Por exemplo, "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'O diretório deve conter arquivos jar, subdiretórios também são aceitos.',
|
||||
|
||||
@@ -1040,6 +1040,29 @@ const message = {
|
||||
'Перед сохранением создаётся одно минимальное изображение; возможна оплата',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'Поиск и загрузка моделей',
|
||||
searchHelper:
|
||||
'Найдите модели в ModelScope или Hugging Face, затем разверните их или создайте Recipe в разделе подготовки моделей.',
|
||||
modelScopeSearchHelper: 'Стабильный доступ в материковом Китае',
|
||||
huggingFaceSearchHelper: 'Большой выбор моделей',
|
||||
searchPlaceholder: 'Введите имя модели или ID репозитория, например Qwen/Qwen3-8B',
|
||||
popularSearches: 'Популярные запросы',
|
||||
searchSort: 'Сортировка',
|
||||
onlyTokenizer: 'Только токенизатор',
|
||||
downloadStatus: 'Статус загрузки',
|
||||
downloaded: 'Загружено',
|
||||
alreadyExists: 'Уже существует',
|
||||
downloadCompleted: 'Загрузка завершена',
|
||||
localFilesMissing: 'Локальные файлы не найдены',
|
||||
ollamaNameHelper:
|
||||
'Введите полное имя модели из библиотеки Ollama. Если тег не указан, используется latest.',
|
||||
downloadHelper: 'Нажмите «Поиск», чтобы найти и загрузить модели из ModelScope и Hugging Face.',
|
||||
serviceHelper:
|
||||
'Подключайте сервисы моделей из публичных облаков, локальных движков инференса и шлюзов ИИ для встроенных агентов 1Panel и внешних агентов, таких как WorkBuddy.',
|
||||
gpuType: 'Тип GPU',
|
||||
vllmVersion: 'Версия vLLM',
|
||||
vllmImage: 'Образ vLLM',
|
||||
servicePort: 'Порт сервиса',
|
||||
gpuAcceleration: 'Ускорение GPU',
|
||||
gpuMode: 'Выбор ускорителей',
|
||||
gpuAll: 'Все ускорители',
|
||||
@@ -1071,7 +1094,14 @@ const message = {
|
||||
approxWeightSize: 'Около {0} ГБ',
|
||||
services: 'Сервисы моделей',
|
||||
addInstance: 'Добавить экземпляр',
|
||||
addService: 'Добавить сервис модели',
|
||||
modelScopeEndpointHelper:
|
||||
'Для поиска и загрузки моделей ModelScope. По умолчанию используется официальный URL.',
|
||||
modelTokenHelper: 'Необязательно. Для закрытых моделей нужен токен с правами доступа.',
|
||||
modelDirHelper: 'Каталог загрузки моделей и источник списка локальных моделей.',
|
||||
featuredModelsHelper:
|
||||
'Официальный каталог рекомендуемых моделей 1Panel. Обновляйте вручную или включите автоматическую синхронизацию каждые 24 часа. Обновляется только каталог, без загрузки файлов моделей.',
|
||||
addInstanceHelper: 'Создайте экземпляр vLLM для обслуживания загруженных моделей.',
|
||||
addService: 'Добавить',
|
||||
onlineModel: 'Онлайн-модели',
|
||||
instanceDeployment: 'Развертывание по экземплярам',
|
||||
engines: 'Локальные движки инференса',
|
||||
@@ -1093,11 +1123,11 @@ const message = {
|
||||
recipeArguments: 'Параметры запуска',
|
||||
recipeImportCommand: 'Импорт команды',
|
||||
recipeImportPlaceholder:
|
||||
'Вставьте сюда команду запуска в формате pip/uv или Docker. 1Panel автоматически разберёт её и заполнит Recipe.',
|
||||
'Вставьте сюда команду запуска в формате pip/uv или docker. 1Panel автоматически разберёт её и заполнит форму.',
|
||||
recipeVariablesNotSupported:
|
||||
'Ссылки на переменные в командах не поддерживаются. Укажите конкретные значения; переменные окружения настройте в соответствующем поле.',
|
||||
recipeImportError:
|
||||
'Не удалось преобразовать. Добавьте команду запуска Docker или vllm serve с моделью; вставляйте команды установки pip/uv вместе с командой запуска.',
|
||||
'Допустимая команда запуска не найдена. Вставьте команду pip/uv или docker, содержащую модель.',
|
||||
engineProvider: 'Движок / Поставщик',
|
||||
endpoint: 'Конечная точка',
|
||||
cloudAccount: 'Облачная учетная запись',
|
||||
@@ -1108,7 +1138,8 @@ const message = {
|
||||
model: 'Модель',
|
||||
localModel: 'Локальные модели',
|
||||
create_helper: 'Загрузить "{0}"',
|
||||
ollama_doc: 'Вы можете посетить официальный сайт Ollama, чтобы искать и находить больше моделей.',
|
||||
ollama_doc:
|
||||
'Найдите модели на {link}. После добавления модель будет загружена автоматически. Убедитесь, что Ollama работает и на диске достаточно места.',
|
||||
container_conn_helper: 'Используйте этот адрес для доступа или подключения между контейнерами',
|
||||
from_remote: 'Эта модель не была загружена через 1Panel, нет связанных журналов извлечения.',
|
||||
no_logs: 'Журналы извлечения для этой модели были удалены и не могут быть просмотрены.',
|
||||
@@ -1129,7 +1160,7 @@ const message = {
|
||||
'Адрес контейнера подходит для контейнеров агентов; 127.0.0.1, системный IP или пользовательский адрес подходит для AI Gateway или внешних сервисов.',
|
||||
containerAddress: 'Адрес контейнера',
|
||||
customAddress: 'Пользовательский адрес',
|
||||
downloader: 'Управление загрузками',
|
||||
downloader: 'Загрузка моделей',
|
||||
modelDirectoryHelper:
|
||||
'По умолчанию список показывает модели, загруженные в каталог, указанный в разделе «Подготовка моделей > Настройки».',
|
||||
modelDirectoryPlaceholder: 'Найти модель или ввести полный путь',
|
||||
@@ -1141,7 +1172,7 @@ const message = {
|
||||
acceleratedEndpointLabel: 'Endpoint ускорения {0}',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper:
|
||||
'Настройте endpoint ускорения, если доступ к HuggingFace нестабилен. Он будет использоваться для поиска, деталей и загрузок.',
|
||||
'Необязательный URL зеркала для поиска, просмотра сведений и загрузки моделей HuggingFace.',
|
||||
sortDefault: 'Сортировка по умолчанию',
|
||||
sortMostParameters: 'Больше всего параметров',
|
||||
sortLeastParameters: 'Меньше всего параметров',
|
||||
@@ -5115,7 +5146,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'Пожалуйста, введите полную команду запуска, например: npm run start. Для команд запуска PM2 замените на pm2-runtime, иначе запуск завершится ошибкой.',
|
||||
portError: 'Не повторяйте один и тот же порт.',
|
||||
systemRestartHelper: 'Описание статуса: Прерывание - получение статуса не удалось из-за перезагрузки системы',
|
||||
javaScriptHelper: 'Укажите полную команду запуска. Например, "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'Директория должна содержать jar файлы, поддиректории также допустимы',
|
||||
goHelper: 'Укажите полную команду запуска. Например, "go run main.go" или "./main".',
|
||||
|
||||
@@ -1050,6 +1050,29 @@ const message = {
|
||||
validateImageAvailabilityHelper: 'Kaydetmeden önce bir küçük görsel üretir ve ücret doğurabilir',
|
||||
},
|
||||
model: {
|
||||
searchTitle: 'Model ara ve indir',
|
||||
searchHelper:
|
||||
'ModelScope veya Hugging Face üzerinde model bulun, ardından Model Hazırlığı bölümünde dağıtın veya bir Recipe oluşturun.',
|
||||
modelScopeSearchHelper: 'Çin ana karasında kararlı erişim',
|
||||
huggingFaceSearchHelper: 'Geniş model koleksiyonu',
|
||||
searchPlaceholder: 'Model adı veya depo kimliği girin, ör. Qwen/Qwen3-8B',
|
||||
popularSearches: 'Popüler aramalar',
|
||||
searchSort: 'Sırala',
|
||||
onlyTokenizer: 'Yalnızca belirteç ayırıcı',
|
||||
downloadStatus: 'İndirme durumu',
|
||||
downloaded: 'İndirildi',
|
||||
alreadyExists: 'Zaten mevcut',
|
||||
downloadCompleted: 'İndirme tamamlandı',
|
||||
localFilesMissing: 'Yerel dosyalar bulunamadı',
|
||||
ollamaNameHelper: 'Ollama kütüphanesindeki tam model adını girin. Etiket belirtilmezse latest kullanılır.',
|
||||
downloadHelper:
|
||||
'ModelScope ve Hugging Face üzerindeki modelleri bulup indirmek için “Ara” düğmesine tıklayın.',
|
||||
serviceHelper:
|
||||
'Genel bulutlardan, yerel çıkarım motorlarından ve AI ağ geçitlerinden model hizmetlerini bağlayarak yerleşik 1Panel ajanları ve WorkBuddy gibi harici ajanlar için kullanıma sunun.',
|
||||
gpuType: 'GPU türü',
|
||||
vllmVersion: 'vLLM sürümü',
|
||||
vllmImage: 'vLLM imajı',
|
||||
servicePort: 'Hizmet portu',
|
||||
gpuAcceleration: 'GPU hızlandırma',
|
||||
gpuMode: 'Hızlandırıcı seçimi',
|
||||
gpuAll: 'Tüm hızlandırıcılar',
|
||||
@@ -1080,7 +1103,14 @@ const message = {
|
||||
approxWeightSize: 'Yaklaşık {0} GB',
|
||||
services: 'Model hizmetleri',
|
||||
addInstance: 'Örnek ekle',
|
||||
addService: 'Model hizmeti ekle',
|
||||
modelScopeEndpointHelper:
|
||||
'ModelScope modellerini aramak ve indirmek için kullanılır. Varsayılan, resmî URL adresidir.',
|
||||
modelTokenHelper: 'İsteğe bağlı. Özel veya kısıtlı modeller için erişim yetkili bir token kullanın.',
|
||||
modelDirHelper: 'Modellerin indirildiği ve yerel model listesinin okunduğu dizin.',
|
||||
featuredModelsHelper:
|
||||
'1Panel resmî öne çıkan model kataloğu. Elle yenileyin veya 24 saatte bir otomatik eşitlemeyi etkinleştirin. Yalnızca katalog güncellenir; model dosyaları indirilmez.',
|
||||
addInstanceHelper: 'İndirilen modelleri sunmak için bir vLLM örneği oluşturun.',
|
||||
addService: 'Ekle',
|
||||
onlineModel: 'Çevrimiçi modeller',
|
||||
instanceDeployment: 'Örnek bazında dağıtım',
|
||||
engines: 'Yerel çıkarım motorları',
|
||||
@@ -1102,11 +1132,11 @@ const message = {
|
||||
recipeArguments: 'Başlatma parametreleri',
|
||||
recipeImportCommand: 'Komut içe aktar',
|
||||
recipeImportPlaceholder:
|
||||
'pip/uv veya Docker biçimindeki başlatma komutunu buraya yapıştırın. 1Panel komutu otomatik olarak ayrıştırıp Recipe alanlarını doldurur.',
|
||||
'pip/uv veya docker biçimindeki başlatma komutunu buraya yapıştırın. 1Panel komutu otomatik olarak ayrıştırıp form alanlarını doldurur.',
|
||||
recipeVariablesNotSupported:
|
||||
'Komutlarda değişken başvuruları desteklenmez. Açık değerler girin; ortam değişkenlerini ilgili alanda yapılandırın.',
|
||||
recipeImportError:
|
||||
'Dönüştürülemedi. Model içeren bir Docker veya vllm serve başlatma komutu ekleyin; pip/uv kurulum komutlarını başlatma komutuyla birlikte yapıştırın.',
|
||||
'Geçerli bir başlatma komutu algılanmadı. Model içeren bir pip/uv veya docker komutu yapıştırın.',
|
||||
engineProvider: 'Motor / Sağlayıcı',
|
||||
endpoint: 'Uç nokta',
|
||||
cloudAccount: 'Bulut hesabı',
|
||||
@@ -1117,7 +1147,8 @@ const message = {
|
||||
model: 'Model',
|
||||
localModel: 'Yerel Modeller',
|
||||
create_helper: '"{0}" çek',
|
||||
ollama_doc: 'Daha fazla model aramak ve bulmak için Ollama resmi web sitesini ziyaret edebilirsiniz.',
|
||||
ollama_doc:
|
||||
'Modelleri {link} adresinde bulun. Model eklendikten sonra otomatik olarak indirilir. Ollama hizmetinin çalıştığından ve yeterli disk alanı olduğundan emin olun.',
|
||||
container_conn_helper: 'Konteynerler arası erişim veya bağlantı için bu adresi kullanın',
|
||||
from_remote: 'Bu model 1Panel aracılığıyla indirilmedi, ilgili çekme logları yok.',
|
||||
no_logs: 'Bu modelin çekme logları silindi ve görüntülenemiyor.',
|
||||
@@ -1137,7 +1168,7 @@ const message = {
|
||||
'Konteyner adresi ajan konteynerleri içindir; 127.0.0.1, sistem IP veya özel adres AI Gateway ya da harici servisler içindir.',
|
||||
containerAddress: 'Konteyner adresi',
|
||||
customAddress: 'Özel adres',
|
||||
downloader: 'İndirme yönetimi',
|
||||
downloader: 'Model indirme',
|
||||
modelDirectoryHelper:
|
||||
'Model listesi varsayılan olarak Model Hazırlığı > Ayarlar bölümünde yapılandırılan dizine indirilen modelleri gösterir.',
|
||||
modelDirectoryPlaceholder: 'Model arayın veya tam yol girin',
|
||||
@@ -1149,7 +1180,7 @@ const message = {
|
||||
acceleratedEndpointLabel: '{0} hızlandırma endpointi',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper:
|
||||
'HuggingFace erişimi kararsız olduğunda bir hızlandırma endpointi yapılandırın. Arama, ayrıntılar ve indirmeler bunu kullanır.',
|
||||
'HuggingFace model aramaları, ayrıntıları ve indirmeleri için isteğe bağlı ayna URL adresi.',
|
||||
sortDefault: 'Varsayılan sıralama',
|
||||
sortMostParameters: 'En çok parametre',
|
||||
sortLeastParameters: 'En az parametre',
|
||||
@@ -5127,8 +5158,6 @@ const message = {
|
||||
customScriptHelper:
|
||||
'Lütfen tam başlatma komutunu girin, örneğin: npm run start. PM2 başlatma komutları için lütfen pm2-runtime ile değiştirin, aksi takdirde başlatma başarısız olacaktır.',
|
||||
portError: 'Aynı portu tekrarlamayın.',
|
||||
systemRestartHelper:
|
||||
'Durum açıklaması: Kesinti - sistem yeniden başlatılması nedeniyle durum alımı başarısız oldu',
|
||||
javaScriptHelper: 'Tam bir başlatma komutu sağlayın. Örneğin, "java -jar halo.jar -Xmx1024M -Xms256M".',
|
||||
javaDirHelper: 'Dizin, jar dosyalarını içermeli, alt dizinler de kabul edilir',
|
||||
goHelper: 'Tam bir başlatma komutu sağlayın. Örneğin, "go run main.go" veya "./main".',
|
||||
|
||||
@@ -980,6 +980,27 @@ const message = {
|
||||
validateImageAvailabilityHelper: '儲存前會實際產生一張最小圖片,可能產生費用',
|
||||
},
|
||||
model: {
|
||||
searchTitle: '搜尋並下載模型',
|
||||
searchHelper: '從 ModelScope 或 Hugging Face 尋找模型,下載後可在模型準備中部署或建立 Recipe。',
|
||||
modelScopeSearchHelper: '中國大陸存取穩定',
|
||||
huggingFaceSearchHelper: '模型資源豐富',
|
||||
searchPlaceholder: '輸入模型名稱或儲存庫 ID,例如 Qwen/Qwen3-8B',
|
||||
popularSearches: '熱門搜尋',
|
||||
searchSort: '排序',
|
||||
onlyTokenizer: '僅下載分詞器',
|
||||
downloadStatus: '下載狀態',
|
||||
downloaded: '已下載',
|
||||
alreadyExists: '已存在',
|
||||
downloadCompleted: '下載完成',
|
||||
localFilesMissing: '找不到本機檔案',
|
||||
ollamaNameHelper: '請填寫 Ollama 模型庫中的完整模型名稱,未指定標籤時預設使用 latest。',
|
||||
downloadHelper: '點擊「搜尋」按鈕,即可查找並下載 ModelScope、Hugging Face 上的模型。',
|
||||
serviceHelper:
|
||||
'統一接入公有雲、本機推論引擎和 AI 閘道等模型服務,供 1Panel 內建智慧體及 WorkBuddy 等外部智慧體呼叫。',
|
||||
gpuType: 'GPU 類型',
|
||||
vllmVersion: 'vLLM 版本',
|
||||
vllmImage: 'vLLM 映像檔',
|
||||
servicePort: '服務連接埠',
|
||||
gpuAcceleration: 'GPU 加速',
|
||||
gpuMode: '加速卡選擇',
|
||||
gpuAll: '全部加速卡',
|
||||
@@ -1010,7 +1031,13 @@ const message = {
|
||||
approxWeightSize: '約 {0} GB',
|
||||
services: '模型服務',
|
||||
addInstance: '新增實例',
|
||||
addService: '新增模型服務',
|
||||
modelScopeEndpointHelper: '用於搜尋和下載 ModelScope 模型,預設使用官方位址。',
|
||||
modelTokenHelper: '選填,存取私人或受限模型時需填寫具備權限的 Token。',
|
||||
modelDirHelper: '模型下載儲存目錄,也用於讀取本機模型清單。',
|
||||
featuredModelsHelper:
|
||||
'1Panel 官方精選模型目錄,可手動重新整理或開啟每 24 小時自動同步,僅更新目錄,不下載模型檔案。',
|
||||
addInstanceHelper: '建立 vLLM 執行個體,將已下載的模型部署為模型服務。',
|
||||
addService: '新增',
|
||||
onlineModel: '線上模型',
|
||||
instanceDeployment: '按執行個體部署',
|
||||
engines: '本機推理引擎',
|
||||
@@ -1031,10 +1058,9 @@ const message = {
|
||||
'前往 {link},依序選擇模型提供商和目標模型,再根據硬體、量化版本及部署策略等選項產生啟動命令。',
|
||||
recipeArguments: '啟動參數',
|
||||
recipeImportCommand: '匯入命令',
|
||||
recipeImportPlaceholder: '貼上 pip/uv 或 Docker 格式的啟動命令,1Panel 將自動解析並填入 Recipe。',
|
||||
recipeImportPlaceholder: '貼上 pip/uv 或 docker 格式的啟動命令,1Panel 將自動解析並填入。',
|
||||
recipeVariablesNotSupported: '命令中不支援變數引用,請填寫具體值;環境變數請在環境變數欄設定。',
|
||||
recipeImportError:
|
||||
'無法轉換,請提供包含模型的 Docker 或 vllm serve 啟動命令;pip/uv 安裝命令需要與啟動命令一起貼上。',
|
||||
recipeImportError: '未識別到有效的啟動命令,請貼上包含模型的 pip/uv 或 docker 命令。',
|
||||
engineProvider: '引擎 / 供應商',
|
||||
endpoint: '端點',
|
||||
cloudAccount: '雲端帳號',
|
||||
@@ -1045,7 +1071,7 @@ const message = {
|
||||
model: '模型',
|
||||
localModel: '本地模型',
|
||||
create_helper: '拉取 "{0}"',
|
||||
ollama_doc: '您可以瀏覽 Ollama 官方網站,搜尋並尋找更多模型。',
|
||||
ollama_doc: '前往 {link} 查找模型,新增後會自動拉取模型,請確保 Ollama 服務正常運作且磁碟空間充足。',
|
||||
container_conn_helper: '容器間瀏覽或連接使用此地址',
|
||||
from_remote: '該模型並非透過 1Panel 下載,無相關拉取日誌。',
|
||||
no_logs: '該模型的拉取日誌已被刪除,無法檢視相關日誌。',
|
||||
@@ -1065,7 +1091,7 @@ const message = {
|
||||
'容器地址適合智能體容器呼叫;127.0.0.1、本機 IP 或自訂地址適合 AI 閘道或外部服務呼叫。',
|
||||
containerAddress: '容器地址',
|
||||
customAddress: '自訂地址',
|
||||
downloader: '下載管理',
|
||||
downloader: '模型下載',
|
||||
modelDirectoryHelper: '模型列表預設來自「模型準備 > 設定」中配置的模型目錄,顯示該目錄下已下載的模型。',
|
||||
modelDirectoryPlaceholder: '搜尋模型或輸入完整路徑',
|
||||
selectModelDirectory: '選擇目錄',
|
||||
@@ -1075,7 +1101,7 @@ const message = {
|
||||
endpointLabel: '{0} 地址',
|
||||
acceleratedEndpointLabel: '{0} 加速地址',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper: '國內存取 HuggingFace 不穩定時可設定加速地址,搜尋、詳情和下載都會使用該地址。',
|
||||
hfEndpointHelper: '選填,用於加速 HuggingFace 模型的搜尋、詳細資訊查詢和下載。',
|
||||
sortDefault: '綜合排序',
|
||||
sortMostParameters: '參數最多',
|
||||
sortLeastParameters: '參數最少',
|
||||
@@ -4695,7 +4721,6 @@ const message = {
|
||||
customScript: '自訂啟動指令',
|
||||
customScriptHelper: '請填寫完整的啟動指令,例:npm run start,pm2 啟動指令請換為 pm2-runtime,否則會啟動失敗',
|
||||
portError: '不能填寫相同連接埠',
|
||||
systemRestartHelper: '狀態說明:中斷-系統重新啟動導致狀態取得失敗',
|
||||
javaScriptHelper: '請填寫完整啟動指令,例:java -jar halo.jar -Xmx1024M -Xms256M',
|
||||
javaDirHelper: '目錄中要包含 jar 包,子目錄中包含也可',
|
||||
goHelper: '請填寫完整啟動指令,例:go run main.go 或 ./main',
|
||||
|
||||
@@ -993,6 +993,27 @@ const message = {
|
||||
validateImageAvailabilityHelper: '保存前会真实生成一张最小图片,可能产生费用',
|
||||
},
|
||||
model: {
|
||||
searchTitle: '搜索并下载模型',
|
||||
searchHelper: '从 ModelScope 或 Hugging Face 查找模型,下载后可在模型准备中部署或创建 Recipe。',
|
||||
modelScopeSearchHelper: '国内访问稳定',
|
||||
huggingFaceSearchHelper: '模型资源丰富',
|
||||
searchPlaceholder: '输入模型名称或仓库 ID,例如 Qwen/Qwen3-8B',
|
||||
popularSearches: '热门搜索',
|
||||
searchSort: '排序',
|
||||
onlyTokenizer: '仅下载分词器',
|
||||
downloadStatus: '下载状态',
|
||||
downloaded: '已下载',
|
||||
alreadyExists: '已存在',
|
||||
downloadCompleted: '下载完成',
|
||||
localFilesMissing: '本地文件未找到',
|
||||
ollamaNameHelper: '请填写 Ollama 模型库中的完整模型名称,未指定标签时默认使用 latest。',
|
||||
downloadHelper: '点击“搜索”按钮,即可查找并下载 ModelScope、Hugging Face 上的模型。',
|
||||
serviceHelper:
|
||||
'统一接入公有云、本地推理引擎和 AI 网关等模型服务,供 1Panel 内置智能体及 WorkBuddy 等外部智能体调用。',
|
||||
gpuType: 'GPU 类型',
|
||||
vllmVersion: 'vLLM 版本',
|
||||
vllmImage: 'vLLM 镜像',
|
||||
servicePort: '服务端口',
|
||||
gpuAcceleration: 'GPU 加速',
|
||||
gpuMode: '加速卡选择',
|
||||
gpuAll: '全部加速卡',
|
||||
@@ -1023,7 +1044,13 @@ const message = {
|
||||
approxWeightSize: '约 {0} GB',
|
||||
services: '模型服务',
|
||||
addInstance: '新增实例',
|
||||
addService: '添加模型服务',
|
||||
modelScopeEndpointHelper: '用于搜索和下载 ModelScope 模型,默认使用官方地址。',
|
||||
modelTokenHelper: '选填,访问私有或受限模型时需填写有权限的 Token。',
|
||||
modelDirHelper: '模型下载保存目录,也用于读取本地模型列表。',
|
||||
featuredModelsHelper:
|
||||
'1Panel 官方精选模型目录,可手动刷新或开启每 24 小时自动同步,仅更新目录,不下载模型文件。',
|
||||
addInstanceHelper: '创建 vLLM 实例,将已下载的模型部署为模型服务。',
|
||||
addService: '添加',
|
||||
onlineModel: '在线模型',
|
||||
instanceDeployment: '按实例部署',
|
||||
engines: '本地推理引擎',
|
||||
@@ -1044,10 +1071,9 @@ const message = {
|
||||
'前往 {link},依次选择模型提供商和目标模型,再根据硬件、量化版本及部署策略等选项生成启动命令。',
|
||||
recipeArguments: '启动参数',
|
||||
recipeImportCommand: '导入命令',
|
||||
recipeImportPlaceholder: '粘贴 pip/uv 或 Docker 格式的启动命令,1Panel 将自动解析并填充 Recipe。',
|
||||
recipeImportPlaceholder: '粘贴 pip/uv 或 docker 格式的启动命令,1Panel 将自动解析并填充。',
|
||||
recipeVariablesNotSupported: '命令中不支持变量引用,请填写具体值;环境变量请在环境变量栏配置。',
|
||||
recipeImportError:
|
||||
'无法转换,请提供包含模型的 Docker 或 vllm serve 启动命令;pip/uv 安装命令需要与启动命令一起粘贴。',
|
||||
recipeImportError: '未识别到有效的启动命令,请粘贴包含模型的 pip/uv 或 docker 命令。',
|
||||
engineProvider: '引擎 / 供应商',
|
||||
endpoint: '端点',
|
||||
cloudAccount: '云端账号',
|
||||
@@ -1058,7 +1084,7 @@ const message = {
|
||||
model: '模型',
|
||||
localModel: '本地模型',
|
||||
create_helper: '拉取 "{0}"',
|
||||
ollama_doc: '您可以访问 Ollama 官网,搜索并查找更多模型。',
|
||||
ollama_doc: '前往 {link} 查找模型,添加后会自动拉取模型,请确保 Ollama 服务正常运行且磁盘空间充足。',
|
||||
container_conn_helper: '容器间访问或连接使用此地址',
|
||||
from_remote: '该模型并非通过 1Panel 下载,无相关拉取日志。',
|
||||
no_logs: '该模型的拉取日志已被删除,无法查看相关日志。',
|
||||
@@ -1078,7 +1104,7 @@ const message = {
|
||||
'容器地址适合智能体容器调用;127.0.0.1、本机 IP 或自定义地址适合 AI 网关或外部服务调用。',
|
||||
containerAddress: '容器地址',
|
||||
customAddress: '自定义地址',
|
||||
downloader: '下载管理',
|
||||
downloader: '模型下载',
|
||||
modelDirectoryHelper: '模型列表默认来自“模型准备 > 设置”中配置的模型目录,展示该目录下已下载的模型。',
|
||||
modelDirectoryPlaceholder: '搜索模型或输入完整路径',
|
||||
selectModelDirectory: '选择目录',
|
||||
@@ -1088,7 +1114,7 @@ const message = {
|
||||
endpointLabel: '{0} 地址',
|
||||
acceleratedEndpointLabel: '{0} 加速地址',
|
||||
tokenLabel: '{0} Token',
|
||||
hfEndpointHelper: '国内访问 HuggingFace 不稳定时可配置加速地址,搜索、详情和下载都会使用该地址。',
|
||||
hfEndpointHelper: '选填,用于加速 HuggingFace 模型的搜索、详情查询和下载。',
|
||||
sortDefault: '综合排序',
|
||||
sortMostParameters: '参数最多',
|
||||
sortLeastParameters: '参数最少',
|
||||
@@ -4737,7 +4763,6 @@ const message = {
|
||||
customScript: '自定义启动命令',
|
||||
customScriptHelper: '请填写完整的启动命令,例如:npm run start,pm2 启动命令请换为 pm2-runtime,否则会启动失败',
|
||||
portError: '不能填写相同端口',
|
||||
systemRestartHelper: '状态说明:中断-系统重启导致状态获取失败',
|
||||
javaScriptHelper: '请填写完整启动命令,例如:java -jar halo.jar -Xmx1024M -Xms256M',
|
||||
javaDirHelper: '目录中要包含 jar 包,子目录中包含也可',
|
||||
goHelper: '请填写完整启动命令,例如:go run main.go 或 ./main',
|
||||
|
||||
@@ -22,6 +22,7 @@ export interface Deployment {
|
||||
}
|
||||
|
||||
interface VllmAPI {
|
||||
listVllmCommandTemplates: () => Promise<ResultData<Array<{ model: string }>>>;
|
||||
pageVllm: (req: ReqPage & { info: string }) => Promise<ResultData<ResPage<Deployment>>>;
|
||||
operateVllm: (
|
||||
req: { id: number; operate: string; taskID: string; forceDelete?: boolean } & Partial<AI.ModelAccountSync>,
|
||||
@@ -52,3 +53,12 @@ export async function readPages<T>(search: (page: ReqPage) => Promise<ResultData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function matchesModelRecipe(recipeModel: string, modelPath: string, repoID = '') {
|
||||
const path = modelPath.replace(/\/+$/, '');
|
||||
const name = path.split('/').pop() || '';
|
||||
const model = recipeModel.trim().replace(/\/+$/, '');
|
||||
return Boolean(
|
||||
model && [repoID || path.split('/').slice(-2).join('/'), path, name, `/models/${name}`].includes(model),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,13 @@
|
||||
:only-icon="true"
|
||||
/>
|
||||
</template>
|
||||
<template #prompt>
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
:title="$t(isLocal ? 'aiTools.model.addInstanceHelper' : 'aiTools.model.serviceHelper')"
|
||||
/>
|
||||
</template>
|
||||
<template #main>
|
||||
<ComplexTable
|
||||
v-if="!isLocal"
|
||||
|
||||
@@ -2,17 +2,24 @@
|
||||
<DrawerPro size="normal" v-model="drawerVisible" :header="$t('commons.button.add')" @close="handleClose">
|
||||
<el-alert type="info" :closable="false">
|
||||
<template #title>
|
||||
<span class="flx-align-center">
|
||||
{{ $t('aiTools.model.ollama_doc') }}
|
||||
<el-button link class="ml-5" icon="Position" @click="goSearch()" type="primary">
|
||||
{{ $t('firewall.quickJump') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<i18n-t keypath="aiTools.model.ollama_doc" tag="span" class="ollama-hint-text">
|
||||
<template #link>
|
||||
<a
|
||||
class="ollama-link"
|
||||
href="https://ollama.com/search"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
ollama.com
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-form ref="formRef" label-position="top" class="mt-5" :model="form">
|
||||
<el-form-item :label="$t('commons.table.name')" :rules="Rules.requiredInput" prop="name">
|
||||
<el-input v-model.trim="form.name" />
|
||||
<el-input v-model.trim="form.name" placeholder="qwen3.6:35b" />
|
||||
<span class="input-help">{{ $t('aiTools.model.ollamaNameHelper') }}</span>
|
||||
<span class="input-help" v-if="form.name">
|
||||
{{
|
||||
$t('aiTools.model.create_helper', [
|
||||
@@ -80,10 +87,6 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
});
|
||||
};
|
||||
|
||||
const goSearch = () => {
|
||||
window.open('https://ollama.com/search', '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisible.value = false;
|
||||
};
|
||||
@@ -92,3 +95,23 @@ defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ollama-hint-text {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.ollama-link {
|
||||
color: var(--el-color-primary);
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ollama-link:hover {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
@is-exist="checkExist"
|
||||
/>
|
||||
</template>
|
||||
<template #prompt>
|
||||
<el-alert type="info" :closable="false" :title="$t('runtime.systemRestartHelper')" />
|
||||
</template>
|
||||
<template #leftToolBar>
|
||||
<el-button v-permission :disabled="modelInfo.status !== 'Running'" type="primary" @click="onCreate">
|
||||
{{ $t('commons.button.add') }}
|
||||
@@ -89,9 +86,14 @@
|
||||
<el-tooltip v-if="row.status === 'Unknown'" :content="row.message" placement="top">
|
||||
<el-tag type="warning">{{ $t('commons.status.unknown') }}</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag v-if="row.status === 'Canceled'" type="danger">
|
||||
{{ $t('commons.status.systemrestart') }}
|
||||
</el-tag>
|
||||
<el-tooltip
|
||||
v-if="row.status === 'Canceled'"
|
||||
:content="row.message"
|
||||
:disabled="!row.message"
|
||||
placement="top"
|
||||
>
|
||||
<el-tag type="danger">{{ $t('commons.status.systemrestart') }}</el-tag>
|
||||
</el-tooltip>
|
||||
<el-tag v-if="row.status === 'Failed'" type="danger">
|
||||
{{ $t('commons.status.failed') }}
|
||||
</el-tag>
|
||||
|
||||
@@ -108,10 +108,23 @@
|
||||
v-if="currentTab === 'downloader'"
|
||||
title="model-download-refresh"
|
||||
:rate="5"
|
||||
@search="loadDownloads"
|
||||
@search="refreshDownloadProgress"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="currentTab === 'featured' || currentTab === 'downloader'" #prompt>
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
:title="
|
||||
$t(
|
||||
currentTab === 'featured'
|
||||
? 'aiTools.model.featuredModelsHelper'
|
||||
: 'aiTools.model.downloadHelper',
|
||||
)
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<template #main>
|
||||
<ComplexTable
|
||||
v-if="currentTab === 'featured'"
|
||||
@@ -214,18 +227,20 @@
|
||||
:pagination-config="downloadPagination"
|
||||
@search="loadDownloads"
|
||||
>
|
||||
<el-table-column prop="source" :label="$t('aiTools.model.modelSource')" width="120">
|
||||
<el-table-column prop="repoID" :label="$t('aiTools.model.repoID')" min-width="280">
|
||||
<template #default="{ row }">
|
||||
{{ sourceLabel(row.source) }}
|
||||
<div class="download-repo-id" :title="row.repoID">{{ row.repoID }}</div>
|
||||
<div class="download-source">
|
||||
<svg-icon
|
||||
v-if="row.source === 'modelscope' || row.source === 'huggingface'"
|
||||
:iconName="row.source === 'modelscope' ? 'p-modelscope' : 'p-huggingface1'"
|
||||
class="download-source-icon"
|
||||
/>
|
||||
<span>{{ sourceLabel(row.source) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="repoID"
|
||||
:label="$t('aiTools.model.repoID')"
|
||||
min-width="240"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column :label="$t('modelDownloadExtra.content')" width="140">
|
||||
<el-table-column :label="$t('commons.table.type')" width="140">
|
||||
<template #default="{ row }">
|
||||
{{
|
||||
$t(
|
||||
@@ -236,59 +251,65 @@
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" :label="$t('commons.table.status')" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip :content="row.errorMessage" :disabled="!row.errorMessage" placement="top">
|
||||
<el-tag :type="statusTagType(row.status)" round effect="light" size="small">
|
||||
<span class="status-tag-content">
|
||||
<span>{{ statusText(row.status) }}</span>
|
||||
<el-icon v-if="row.status === 'Downloading'" class="is-loading">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</span>
|
||||
</el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('aiTools.model.progress')" min-width="220">
|
||||
<el-table-column prop="status" :label="$t('aiTools.model.downloadStatus')" min-width="260">
|
||||
<template #default="{ row }">
|
||||
<div class="progress-cell">
|
||||
<el-progress
|
||||
class="progress-bar"
|
||||
:percentage="formatProgress(row.progress)"
|
||||
:stroke-width="6"
|
||||
/>
|
||||
<span
|
||||
v-if="formatSizePair(row.downloadedSize, row.totalSize)"
|
||||
class="progress-size"
|
||||
:title="formatSizePair(row.downloadedSize, row.totalSize)"
|
||||
>
|
||||
{{ formatSizePair(row.downloadedSize, row.totalSize) }}
|
||||
</span>
|
||||
<div class="progress-track">
|
||||
<el-progress
|
||||
:percentage="formatProgress(row.progress)"
|
||||
:show-text="false"
|
||||
:stroke-width="4"
|
||||
/>
|
||||
<span class="progress-percentage">{{ formatProgress(row.progress) }}%</span>
|
||||
</div>
|
||||
<div class="download-size-row">
|
||||
<span class="progress-size">
|
||||
{{
|
||||
row.status === 'Success'
|
||||
? row.localModel
|
||||
? row.localModel.sizeFormatted || formatBytes(row.localModel.size)
|
||||
: '—'
|
||||
: formatSizePair(row.downloadedSize, row.totalSize) || '—'
|
||||
}}
|
||||
</span>
|
||||
<el-tooltip :content="statusText(row, true)" placement="top">
|
||||
<span class="download-status" :aria-label="statusText(row, true)" tabindex="0">
|
||||
<el-icon
|
||||
class="download-status-icon"
|
||||
:class="{ 'is-loading': row.status === 'Downloading' }"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<Loading v-if="row.status === 'Downloading'" />
|
||||
<Warning v-else-if="row.status === 'Success' && !row.localModel" />
|
||||
<Select v-else-if="row.status === 'Success'" />
|
||||
<Close v-else-if="row.status === 'Failed'" />
|
||||
<Minus v-else-if="row.status === 'Canceled'" />
|
||||
<Clock v-else />
|
||||
</el-icon>
|
||||
<span class="download-status-text">{{ statusText(row) }}</span>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="targetDir"
|
||||
:label="$t('aiTools.model.modelDir')"
|
||||
min-width="260"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<el-table-column prop="targetDir" :label="$t('aiTools.model.modelDir')" width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-permission:view="'host_file_view'"
|
||||
link
|
||||
type="primary"
|
||||
class="model-path-link"
|
||||
:title="row.targetDir"
|
||||
@click="openLocalModelPath(row.targetDir)"
|
||||
>
|
||||
{{ row.targetDir }}
|
||||
</el-button>
|
||||
<el-tooltip :content="row.targetDir" placement="top">
|
||||
<el-button
|
||||
v-permission:view="'host_file_view'"
|
||||
link
|
||||
type="primary"
|
||||
:aria-label="$t('aiTools.model.modelDir') + ': ' + row.targetDir"
|
||||
@click="openLocalModelPath(row.targetDir)"
|
||||
>
|
||||
<el-icon><Folder /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('file.size')" width="120">
|
||||
<template #default="{ row }">{{ row.localModel?.sizeFormatted || '-' }}</template>
|
||||
<el-table-column prop="recipeCount" label="Recipes" width="90" align="center">
|
||||
<template #default="{ row }">{{ row.recipeCount ?? '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" :label="$t('commons.table.date')" width="180" />
|
||||
<el-table-column :label="$t('commons.table.operate')" width="240" fixed="right">
|
||||
@@ -300,8 +321,9 @@
|
||||
{{ $t('commons.button.retry') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.downloadType === 'all' && row.status === 'Success' && row.localModel"
|
||||
v-if="row.status === 'Success' && row.localModel"
|
||||
v-permission
|
||||
:disabled="row.downloadType === 'tokenizer'"
|
||||
link
|
||||
type="primary"
|
||||
@click="emit('deploy', row.localModel.path)"
|
||||
@@ -309,14 +331,9 @@
|
||||
{{ $t('aiTools.model.deploy') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="
|
||||
recipesView &&
|
||||
isProductPro &&
|
||||
row.downloadType === 'all' &&
|
||||
row.status === 'Success' &&
|
||||
row.localModel
|
||||
"
|
||||
v-if="recipesView && isProductPro && row.status === 'Success' && row.localModel"
|
||||
v-permission
|
||||
:disabled="row.downloadType === 'tokenizer'"
|
||||
link
|
||||
type="primary"
|
||||
@click="
|
||||
@@ -352,6 +369,7 @@
|
||||
<el-col :xs="24" :sm="20" :md="15" :lg="12" :xl="12">
|
||||
<el-form-item :label="$t('aiTools.model.modelDir')" prop="modelDir">
|
||||
<el-input v-model="settings.modelDir" />
|
||||
<span class="input-help">{{ $t('aiTools.model.modelDirHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('aiTools.model.acceleratedEndpointLabel', ['HuggingFace'])"
|
||||
@@ -362,6 +380,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('aiTools.model.tokenLabel', ['HuggingFace'])" prop="hfToken">
|
||||
<el-input v-model="settings.hfToken" show-password />
|
||||
<span class="input-help">{{ $t('aiTools.model.modelTokenHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('aiTools.model.endpointLabel', ['ModelScope'])"
|
||||
@@ -371,12 +390,14 @@
|
||||
v-model="settings.modelScopeEndpoint"
|
||||
placeholder="https://www.modelscope.cn"
|
||||
/>
|
||||
<span class="input-help">{{ $t('aiTools.model.modelScopeEndpointHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('aiTools.model.tokenLabel', ['ModelScope'])"
|
||||
prop="modelScopeToken"
|
||||
>
|
||||
<el-input v-model="settings.modelScopeToken" show-password />
|
||||
<span class="input-help">{{ $t('aiTools.model.modelTokenHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
@@ -395,23 +416,57 @@
|
||||
</template>
|
||||
</LayoutContent>
|
||||
|
||||
<DrawerPro v-model="searchOpen" :header="$t('commons.button.search')" size="50%" :full-screen="true">
|
||||
<DrawerPro
|
||||
v-model="searchOpen"
|
||||
:header="$t('aiTools.model.searchTitle')"
|
||||
:size="isMobile ? 'full' : 'min(1100px, 90vw)'"
|
||||
:full-screen="true"
|
||||
>
|
||||
<el-alert class="search-intro" type="info" :closable="false" :title="$t('aiTools.model.searchHelper')" />
|
||||
<div class="source-switch">
|
||||
<SourceSelect
|
||||
v-model="currentSource"
|
||||
:sources="['modelscope', 'huggingface']"
|
||||
show-description
|
||||
@update:model-value="handleSourceChange"
|
||||
/>
|
||||
</div>
|
||||
<form class="search-row" @submit.prevent="handleSearchSubmit">
|
||||
<el-input
|
||||
v-model="searchForm.query"
|
||||
class="search-input"
|
||||
clearable
|
||||
:placeholder="$t('aiTools.model.searchPlaceholder')"
|
||||
:aria-label="$t('aiTools.model.searchPlaceholder')"
|
||||
/>
|
||||
<el-button type="primary" native-type="submit" :loading="searchCardLoading">
|
||||
{{ $t('commons.button.search') }}
|
||||
</el-button>
|
||||
</form>
|
||||
<div class="popular-searches">
|
||||
<span>{{ $t('aiTools.model.popularSearches') }}</span>
|
||||
<el-button
|
||||
v-for="keyword in ['Qwen3', 'DeepSeek', 'GLM', 'embedding']"
|
||||
:key="keyword"
|
||||
link
|
||||
type="primary"
|
||||
@click="
|
||||
searchForm.query = keyword;
|
||||
handleSearchSubmit();
|
||||
"
|
||||
>
|
||||
{{ keyword }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-loading="searchCardLoading">
|
||||
<div class="search-row">
|
||||
<TableSearch
|
||||
v-model:searchName="searchForm.query"
|
||||
class="search-input"
|
||||
placeholder="Qwen"
|
||||
@search="handleSearchSubmit"
|
||||
/>
|
||||
<el-select v-model="searchForm.sort" class="sort-select" @change="handleSortChange">
|
||||
<div class="search-results-toolbar">
|
||||
<el-select
|
||||
v-model="searchForm.sort"
|
||||
class="sort-select"
|
||||
:aria-label="$t('aiTools.model.searchSort')"
|
||||
@change="handleSortChange"
|
||||
>
|
||||
<template #prefix>{{ $t('aiTools.model.searchSort') }}</template>
|
||||
<el-option
|
||||
v-for="item in sortOptions"
|
||||
:key="item.value"
|
||||
@@ -448,9 +503,18 @@
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('file.size')" width="110">
|
||||
<template #default="{ row }">
|
||||
{{ row.size > 0 ? row.sizeFormatted || formatBytes(row.size) : '—' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="downloads" :label="$t('aiTools.model.downloadsCount')" width="130" />
|
||||
<el-table-column prop="likes" :label="$t('aiTools.model.likes')" width="90" />
|
||||
<el-table-column :label="$t('commons.table.operate')" width="200" fixed="right">
|
||||
<el-table-column
|
||||
:label="$t('commons.table.operate')"
|
||||
min-width="240"
|
||||
:fixed="isMobile ? false : 'right'"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-permission
|
||||
@@ -459,7 +523,7 @@
|
||||
icon="Download"
|
||||
@click="downloadRef?.acceptParams(row.repoID, 'all', [currentSource])"
|
||||
>
|
||||
{{ $t('aiTools.model.model') }}
|
||||
{{ $t('commons.button.download') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-permission
|
||||
@@ -468,7 +532,7 @@
|
||||
icon="Download"
|
||||
@click="downloadRef?.acceptParams(row.repoID, 'tokenizer', [currentSource])"
|
||||
>
|
||||
{{ $t('aiTools.benchmark.tokenizer') }}
|
||||
{{ $t('aiTools.model.onlyTokenizer') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -524,6 +588,7 @@ import {
|
||||
updateFeaturedModelsSync,
|
||||
} from '@/api/modules/model-downloader';
|
||||
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||
import { loadVllmAPI, matchesModelRecipe } from '@/views/ai/model/deployment';
|
||||
|
||||
const emit = defineEmits<{ deploy: [modelDir: string] }>();
|
||||
const { currentNode, isMobile, isOffline, language, isProductPro } = useGlobalStore();
|
||||
@@ -579,7 +644,7 @@ const featuredFields = [
|
||||
] as const;
|
||||
const currentSource = ref<DownloaderSource>('modelscope');
|
||||
const models = ref<ModelDownloader.ModelItem[]>([]);
|
||||
const downloads = ref<ModelDownloader.TaskItem[]>([]);
|
||||
const downloads = ref<Array<ModelDownloader.TaskItem & { recipeCount?: number }>>([]);
|
||||
const searchOpen = ref(false);
|
||||
watch(
|
||||
[currentSource, currentNode, searchOpen],
|
||||
@@ -629,7 +694,7 @@ const searchForm = reactive<ModelDownloader.ModelSearch>({
|
||||
|
||||
const searchPagination = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 50,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
@@ -751,9 +816,58 @@ const changeDownloadType = async () => {
|
||||
};
|
||||
|
||||
let downloadRequest = 0;
|
||||
let refreshingProgress = false;
|
||||
const refreshDownloadProgress = async () => {
|
||||
if (refreshingProgress || currentTab.value !== 'downloader') return;
|
||||
const ids = downloads.value
|
||||
.filter((row) => row.id && ['Waiting', 'Downloading'].includes(row.status))
|
||||
.map((row) => row.id);
|
||||
if (!ids.length) return;
|
||||
const request = downloadRequest;
|
||||
const node = currentNode.value;
|
||||
refreshingProgress = true;
|
||||
try {
|
||||
const { data } = await pageModelDownloadTasks({
|
||||
ids,
|
||||
page: 1,
|
||||
pageSize: ids.length,
|
||||
info: '',
|
||||
status: '',
|
||||
includeLocal: true,
|
||||
});
|
||||
if (node !== currentNode.value || request !== downloadRequest || currentTab.value !== 'downloader') return;
|
||||
const tasks = new Map((data.items || []).map((item) => [item.id, item]));
|
||||
for (const row of downloads.value) {
|
||||
const task = tasks.get(row.id);
|
||||
if (!task) continue;
|
||||
row.status = task.status;
|
||||
row.progress = task.progress;
|
||||
row.totalSize = task.totalSize;
|
||||
row.downloadedSize = task.downloadedSize;
|
||||
row.errorMessage = task.errorMessage;
|
||||
row.startedAt = task.startedAt;
|
||||
row.completedAt = task.completedAt;
|
||||
row.canCancel = task.canCancel;
|
||||
row.canRetry = task.canRetry;
|
||||
row.canRemoveRecord = task.canRemoveRecord;
|
||||
row.localModel = task.localModel;
|
||||
}
|
||||
} finally {
|
||||
refreshingProgress = false;
|
||||
}
|
||||
};
|
||||
|
||||
const loadDownloads = async () => {
|
||||
const request = ++downloadRequest;
|
||||
const node = currentNode.value;
|
||||
const recipeResult = Promise.allSettled([
|
||||
recipesView && isProductPro.value
|
||||
? loadVllmAPI().then((api) => {
|
||||
if (node !== currentNode.value || request !== downloadRequest) return;
|
||||
return api.listVllmCommandTemplates();
|
||||
})
|
||||
: Promise.resolve(undefined),
|
||||
]);
|
||||
const res = await pageModelDownloadTasks({
|
||||
page: downloadPagination.currentPage,
|
||||
pageSize: downloadPagination.pageSize,
|
||||
@@ -769,6 +883,16 @@ const loadDownloads = async () => {
|
||||
if (downloadPagination.currentPage > lastPage) {
|
||||
downloadPagination.currentPage = lastPage;
|
||||
await loadDownloads();
|
||||
return;
|
||||
}
|
||||
const [result] = await recipeResult;
|
||||
if (node !== currentNode.value || request !== downloadRequest) return;
|
||||
const recipes = result.status === 'fulfilled' ? result.value?.data : undefined;
|
||||
for (const row of downloads.value) {
|
||||
row.recipeCount =
|
||||
row.downloadType === 'tokenizer'
|
||||
? 0
|
||||
: recipes?.filter((recipe) => matchesModelRecipe(recipe.model, row.targetDir, row.repoID)).length;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -861,34 +985,32 @@ const refreshCurrent = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const statusTagType = (status: string) => {
|
||||
switch (status) {
|
||||
case 'Success':
|
||||
return 'success';
|
||||
const statusText = (row: ModelDownloader.TaskItem, withDetail = false) => {
|
||||
let key = 'commons.status.waiting';
|
||||
switch (row.status) {
|
||||
case 'Downloading':
|
||||
return 'primary';
|
||||
key = 'aiTools.model.downloading';
|
||||
break;
|
||||
case 'Success':
|
||||
key = !row.localModel
|
||||
? 'aiTools.model.downloadCompleted'
|
||||
: row.id
|
||||
? 'aiTools.model.downloaded'
|
||||
: 'aiTools.model.alreadyExists';
|
||||
break;
|
||||
case 'Failed':
|
||||
key = 'commons.status.failed';
|
||||
break;
|
||||
case 'Canceled':
|
||||
return 'danger';
|
||||
default:
|
||||
return 'info';
|
||||
key = 'aiTools.model.canceled';
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const statusText = (status: string) => {
|
||||
if (status === 'Downloading') {
|
||||
return i18n.global.t('aiTools.model.downloading');
|
||||
}
|
||||
if (status === 'Success') {
|
||||
return i18n.global.t('commons.status.success');
|
||||
}
|
||||
if (status === 'Failed') {
|
||||
return i18n.global.t('commons.status.failed');
|
||||
}
|
||||
if (status === 'Canceled') {
|
||||
return i18n.global.t('aiTools.model.canceled');
|
||||
}
|
||||
return i18n.global.t('commons.status.waiting');
|
||||
if (!withDetail) return i18n.global.t(key);
|
||||
const detail =
|
||||
row.status === 'Success' && !row.localModel
|
||||
? i18n.global.t('aiTools.model.localFilesMissing')
|
||||
: row.errorMessage;
|
||||
return [i18n.global.t(key), detail].filter(Boolean).join(':');
|
||||
};
|
||||
|
||||
const sourceLabel = (source: string) => {
|
||||
@@ -903,7 +1025,7 @@ const sourceLabel = (source: string) => {
|
||||
|
||||
const formatBytes = (value: number) => {
|
||||
if (!value) {
|
||||
return '-';
|
||||
return '0 B';
|
||||
}
|
||||
if (value < 1024 * 1024) {
|
||||
return `${(value / 1024).toFixed(1)} KB`;
|
||||
@@ -945,6 +1067,8 @@ watch(currentTab, async (value) => {
|
||||
});
|
||||
|
||||
watch(currentNode, async () => {
|
||||
downloadRequest++;
|
||||
downloads.value = [];
|
||||
recipeModelPath.value = '';
|
||||
featuredRequest++;
|
||||
featuredLoading.value = false;
|
||||
@@ -1062,6 +1186,10 @@ onMounted(() => {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.search-intro {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.source-switch {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@@ -1075,63 +1203,123 @@ onMounted(() => {
|
||||
.search-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.search-button) {
|
||||
width: 100%;
|
||||
.popular-searches {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 16px;
|
||||
margin-top: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
|
||||
.el-button {
|
||||
margin-left: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-results-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.sort-select {
|
||||
flex: 0 0 160px;
|
||||
width: 160px;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.download-repo-id {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.download-source {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-top: 6px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.download-source-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.progress-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
display: grid;
|
||||
grid-template-rows: 16px 16px;
|
||||
gap: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.status-tag-content {
|
||||
.progress-track {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
|
||||
:deep(.el-progress) {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.progress-percentage {
|
||||
flex-shrink: 0;
|
||||
width: 42px;
|
||||
text-align: right;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.download-size-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.download-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-left: auto;
|
||||
min-width: 0;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
flex: 1;
|
||||
min-width: 110px;
|
||||
.download-status-text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.el-progress__text) {
|
||||
min-width: 36px;
|
||||
margin-left: 6px;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.download-status-icon {
|
||||
flex-shrink: 0;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.progress-size {
|
||||
min-width: 0;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
line-height: 16px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.model-path-link {
|
||||
max-width: 100%;
|
||||
justify-content: flex-start;
|
||||
|
||||
:deep(> span) {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,7 +10,22 @@
|
||||
@click="modelValue = source"
|
||||
>
|
||||
<svg-icon :iconName="source === 'modelscope' ? 'p-modelscope' : 'p-huggingface1'" class="source-icon" />
|
||||
<span class="source-name">{{ source === 'modelscope' ? 'ModelScope' : 'HuggingFace' }}</span>
|
||||
<span class="source-content">
|
||||
<span class="source-heading">
|
||||
<span class="source-name">{{ source === 'modelscope' ? 'ModelScope' : 'Hugging Face' }}</span>
|
||||
<el-tag v-if="showDescription && source === 'modelscope'" size="small" effect="plain">
|
||||
{{ $t('home.recommend') }}
|
||||
</el-tag>
|
||||
</span>
|
||||
<span v-if="showDescription" class="source-description">
|
||||
{{
|
||||
$t(
|
||||
'aiTools.model.' +
|
||||
(source === 'modelscope' ? 'modelScopeSearchHelper' : 'huggingFaceSearchHelper'),
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -18,7 +33,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { ModelDownloader } from '@/api/interface/model-downloader';
|
||||
|
||||
defineProps<{ sources: ModelDownloader.Source[]; disabled?: boolean }>();
|
||||
defineProps<{ sources: ModelDownloader.Source[]; disabled?: boolean; showDescription?: boolean }>();
|
||||
const modelValue = defineModel<ModelDownloader.Source>({ required: true });
|
||||
</script>
|
||||
|
||||
@@ -68,4 +83,23 @@ const modelValue = defineModel<ModelDownloader.Source>({ required: true });
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.source-content {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.source-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.source-description {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user