fix: improve ai benchmark i18n (#12686)

This commit is contained in:
ssongliu
2026-05-21 12:37:33 +08:00
committed by zhengkunwang223
parent ff5c6e878e
commit 11771b2b53
23 changed files with 481 additions and 33 deletions
-10
View File
@@ -997,16 +997,6 @@ func (b *BaseApi) BatchChangeModeAndOwner(c *gin.Context) {
helper.Success(c)
}
func (b *BaseApi) GetPathByType(c *gin.Context) {
pathType, ok := c.Params.Get("type")
if !ok {
helper.BadRequest(c, errors.New("error pathType id in path"))
return
}
resPath := fileService.GetPathByType(pathType)
helper.SuccessWithData(c, resPath)
}
// @Tags File
// @Summary system mount
// @Accept json
+10
View File
@@ -134,6 +134,16 @@ func (b *BaseApi) UpdateFileHistorySetting(c *gin.Context) {
helper.Success(c)
}
// @Tags System Setting
// @Summary Load website dir
// @Success 200 {string} path
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/website/dir [get]
func (b *BaseApi) LoadWebsiteDir(c *gin.Context) {
helper.SuccessWithData(c, settingService.GetWebsiteDir())
}
// @Tags System Setting
// @Summary Load local backup dir
// @Success 200 {string} path
-12
View File
@@ -76,7 +76,6 @@ type IFileService interface {
BatchChangeModeAndOwner(op request.FileRoleReq) error
ReadLogByLine(req request.FileReadByLineReq) (*response.FileLineContent, error)
GetPathByType(pathType string) string
BatchCheckFiles(req request.FilePathsCheck) []response.ExistFileInfo
GetHostMount() []dto.DiskInfo
GetUsersAndGroups() (*response.UserGroupResponse, error)
@@ -1128,17 +1127,6 @@ func (f *FileService) ReadLogByLine(req request.FileReadByLineReq) (*response.Fi
return res, nil
}
func (f *FileService) GetPathByType(pathType string) string {
if pathType == "websiteDir" {
value, _ := settingRepo.GetValueByKey("WEBSITE_DIR")
if value == "" {
return path.Join(global.Dir.BaseDir, "1panel", "www")
}
return value
}
return ""
}
func (f *FileService) BatchCheckFiles(req request.FilePathsCheck) []response.ExistFileInfo {
fileList := make([]response.ExistFileInfo, 0, len(req.Paths))
for _, filePath := range req.Paths {
+11
View File
@@ -4,6 +4,7 @@ import (
"encoding/base64"
"encoding/json"
"errors"
"path"
"strconv"
"strings"
"time"
@@ -15,6 +16,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/app/repo"
"github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
"github.com/1Panel-dev/1Panel/agent/utils/ssh"
terminalai "github.com/1Panel-dev/1Panel/agent/utils/terminal/ai"
@@ -28,6 +30,7 @@ type ISettingService interface {
GetTerminalAIInfo() (*dto.TerminalAIInfo, error)
GetFileManageAIInfo() (*dto.FileManageAIInfo, error)
GetFileHistorySettingInfo() (*response.FileHistorySettingInfo, error)
GetWebsiteDir() string
Update(key, value string) error
UpdateTerminalAI(req dto.TerminalAIInfo) error
UpdateFileManageAI(req dto.FileManageAIInfo) error
@@ -112,6 +115,14 @@ func (u *SettingService) GetFileHistorySettingInfo() (*response.FileHistorySetti
return historyService.GetSettingInfo()
}
func (u *SettingService) GetWebsiteDir() string {
value, _ := settingRepo.GetValueByKey("WEBSITE_DIR")
if value == "" {
return path.Join(global.Dir.BaseDir, "1panel", "www")
}
return value
}
func (u *SettingService) Update(key, value string) error {
return settingRepo.UpdateOrCreate(key, value)
}
+1
View File
@@ -438,6 +438,7 @@ Clamscan: '掃描 {{ .name }}'
TaskScan: '掃描'
OllamaModelPull: '拉取 Ollama 模型{{ .name }}'
OllamaModelSize: '取得 Ollama 模型{{ .name }} 大小'
AIBenchmarkRun: '執行 AI 基準測試'
Snapshot: '快照'
SnapDBInfo: '寫入1Panel 資料庫資訊'
SnapCopy: '複製檔案&目錄{{ .name }}'
-1
View File
@@ -66,7 +66,6 @@ func (f *FileRouter) InitRouter(Router *gin.RouterGroup) {
fileRouter.POST("/favorite", baseApi.CreateFavorite)
fileRouter.POST("/favorite/del", baseApi.DeleteFavorite)
fileRouter.GET("/path/:type", baseApi.GetPathByType)
fileRouter.POST("/mount", baseApi.GetHostMount)
fileRouter.POST("/user/group", baseApi.GetUsersAndGroups)
fileRouter.POST("/convert", baseApi.ConvertFile)
+1
View File
@@ -15,6 +15,7 @@ func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) {
settingRouter.POST("/terminal/ai/search", baseApi.GetTerminalAISettingInfo)
settingRouter.POST("/files/ai/search", baseApi.GetFileManageAISettingInfo)
settingRouter.POST("/file-history/search", baseApi.GetFileHistorySettingInfo)
settingRouter.GET("/website/dir", baseApi.LoadWebsiteDir)
settingRouter.GET("/search/available", baseApi.GetSystemAvailable)
settingRouter.POST("/update", baseApi.UpdateSetting)
settingRouter.POST("/terminal/ai/update", baseApi.UpdateTerminalAISetting)
+1
View File
@@ -125,6 +125,7 @@ TaskUpgrade: "升級"
TaskSync: "同步"
TaskSyncForNode: "同步節點資料"
TaskBackup: "備份"
AIBenchmarkRun: "執行 AI 基準測試"
SuccessStatus: "{{ .name }} 成功"
FailedStatus: "{{ .name }} 失敗 {{ .err }}"
Start: "開始"
-4
View File
@@ -221,10 +221,6 @@ export const getRecycleStatusByNode = (node: string) => {
return http.get<string>('files/recycle/status?operateNode=' + node);
};
export const getPathByType = (pathType: string) => {
return http.get<string>(`files/path/${pathType}`);
};
export const searchHostMount = () => {
return http.post<Dashboard.DiskInfo[]>(`/files/mount`);
};
+3
View File
@@ -72,6 +72,9 @@ export const loadBaseDir = (node?: string) => {
const query = node ? `?operateNode=${node}` : '';
return http.get<string>(`/settings/basedir${query}`);
};
export const loadWebsiteDir = () => {
return http.get<string>(`/settings/website/dir`);
};
export const loadDaemonJsonPath = () => {
return http.get<string>(`/settings/daemonjson`, {});
};
+3
View File
@@ -29,6 +29,7 @@ const message = {
conn: 'Connect',
disConn: 'Disconnect',
clean: 'Clear',
cleanAll: 'Clear all',
selectAll: 'Select all',
login: 'Sign in',
close: 'Close',
@@ -3835,6 +3836,8 @@ const message = {
ai_mcp_view: 'MCP View',
ai_mcp_manage: 'MCP Manage',
ai_gpu_view: 'GPU View',
ai_benchmark_view: 'AI Benchmark View',
ai_benchmark_manage: 'AI Benchmark Manage',
website_view: 'Website View',
website_manage: 'Website Manage',
website_cert_view: 'Certificate View',
+56
View File
@@ -29,6 +29,7 @@ const message = {
conn: 'Conectar',
disconn: 'Desconectar',
clean: 'Limpiar',
cleanAll: 'Limpiar todo',
selectAll: 'Seleccionar todo',
login: 'Iniciar sesión',
close: 'Cerrar',
@@ -1001,6 +1002,59 @@ const message = {
validationModelMapEmpty: 'Los nombres del mapeo de modelos no pueden estar vacíos',
validationModelMapDuplicate: 'El modelo solicitado {0} está duplicado',
},
benchmark: {
title: 'Benchmark',
create: 'Crear',
launchCommand: 'Comando de inicio',
retest: 'Volver a probar',
statusRunning: 'En ejecución',
statusWaiting: 'En espera',
base: 'Información básica',
backend: 'Backend',
baseUrl: 'URL base',
endpoint: 'Endpoint',
tokenizer: 'Tokenizador',
tokenizerPlaceholder:
'Seleccione o introduzca un directorio local de tokenizador, p. ej. /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: 'Configuración de ejecución',
rawResult: 'Resultado bruto',
resultMetrics: 'Métricas de resultado',
contextTokens: 'Longitud de contexto',
contextTokensHelper: 'Suma del límite de tokens de entrada y salida de este benchmark.',
outputThroughput: 'Rendimiento de salida',
outputThroughputHelper: 'Tokens de salida generados por segundo. Un valor mayor indica más velocidad.',
totalThroughput: 'Rendimiento total',
totalThroughputHelper:
'Tokens de entrada y salida procesados por segundo. Se usa para medir la capacidad general.',
firstTokenLatency: 'Latencia del primer token',
firstTokenLatencyHelper:
'Tiempo desde el envío de la solicitud hasta recibir el primer token. Un valor menor indica respuesta más rápida.',
inputTokens: 'Tokens de entrada',
outputTokens: 'Tokens de salida',
tokenValueHelper: 'Introduzca un entero positivo o valor con k, p. ej. 512, 1k, 32k',
numPrompts: 'Prompts',
concurrency: 'Concurrencia',
requestRate: 'Tasa de solicitudes',
requestRateUnlimited: 'Ilimitado (máximo rendimiento)',
requestRateCustom: 'QPS personalizado',
requestRateCustomPlaceholder: 'Solicitudes por segundo, p. ej. 2.5',
successfulRequests: 'Solicitudes correctas',
failedRequests: 'Solicitudes fallidas',
requestThroughput: 'Rendimiento de solicitudes',
ttftMean: 'TTFT promedio',
ttftMedian: 'TTFT mediana',
ttftP99: 'TTFT P99',
tpotMean: 'TPOT promedio',
tpotMedian: 'TPOT mediana',
tpotP99: 'TPOT P99',
itlMean: 'ITL promedio',
itlMedian: 'ITL mediana',
itlP99: 'ITL P99',
timeout: 'Tiempo de espera (segundos)',
image: 'Imagen vLLM',
ignoreEos: 'Ignorar EOS',
extraHeaders: 'Encabezados adicionales',
},
gpu: {
gpu: 'Monitoreo de GPU',
gpuHelper: 'El sistema no detectó comandos NVIDIA-SMI o XPU-SMI. ¡Compruebe e inténtelo de nuevo!',
@@ -3822,6 +3876,8 @@ const message = {
ai_mcp_view: 'Vista de MCP',
ai_mcp_manage: 'Gestión de MCP',
ai_gpu_view: 'Vista de GPU',
ai_benchmark_view: 'Vista de benchmark de IA',
ai_benchmark_manage: 'Gestión de benchmark de IA',
website_view: 'Vista del sitio web',
website_manage: 'Gestión del sitio web',
website_cert_view: 'Vista de certificados',
+54
View File
@@ -26,6 +26,7 @@ const message = {
conn: '接続',
disConn: '切断',
clean: 'クリア',
cleanAll: 'すべてクリア',
selectAll: 'すべて選択',
login: 'サインイン',
close: '閉じる',
@@ -991,6 +992,57 @@ const message = {
validationModelMapEmpty: 'モデルマッピングのモデル名は空にできません',
validationModelMapDuplicate: 'リクエストモデル {0} が重複しています',
},
benchmark: {
title: 'ベンチマーク',
create: '作成',
launchCommand: '起動コマンド',
retest: '再テスト',
statusRunning: '実行中',
statusWaiting: '待機中',
base: '基本情報',
backend: 'バックエンド',
baseUrl: 'Base URL',
endpoint: 'エンドポイント',
tokenizer: 'トークナイザー',
tokenizerPlaceholder:
'ローカルトークナイザーディレクトリを選択または入力してください: /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: '実行設定',
rawResult: '生データ',
resultMetrics: '結果指標',
contextTokens: 'コンテキスト長',
contextTokensHelper: 'このベンチマークの入力 Token 上限と出力 Token 上限の合計です',
outputThroughput: '出力スループット',
outputThroughputHelper: '1 秒あたりに生成される出力 Token 数です高いほど生成が速くなります',
totalThroughput: '合計スループット',
totalThroughputHelper: '1 秒あたりに処理される入力と出力 Token の合計で全体性能の測定に使います',
firstTokenLatency: '初回 Token レイテンシ',
firstTokenLatencyHelper: 'リクエスト送信から最初の Token 受信までの時間です低いほど応答が速くなります',
inputTokens: '入力 Token',
outputTokens: '出力 Token',
tokenValueHelper: '正の整数または k 単位を入力してください: 5121k32k',
numPrompts: 'プロンプト数',
concurrency: '同時実行数',
requestRate: 'リクエストレート',
requestRateUnlimited: '無制限最大スループット',
requestRateCustom: 'カスタム QPS',
requestRateCustomPlaceholder: '1 秒あたりのリクエスト数: 2.5',
successfulRequests: '成功リクエスト',
failedRequests: '失敗リクエスト',
requestThroughput: 'リクエストスループット',
ttftMean: '平均 TTFT',
ttftMedian: '中央値 TTFT',
ttftP99: 'P99 TTFT',
tpotMean: '平均 TPOT',
tpotMedian: '中央値 TPOT',
tpotP99: 'P99 TPOT',
itlMean: '平均 ITL',
itlMedian: '中央値 ITL',
itlP99: 'P99 ITL',
timeout: 'タイムアウト',
image: 'vLLM イメージ',
ignoreEos: 'EOS を無視',
extraHeaders: '追加ヘッダー',
},
gpu: {
gpu: 'GPU 監視',
gpuHelper:
@@ -3806,6 +3858,8 @@ const message = {
ai_mcp_view: 'MCP 表示',
ai_mcp_manage: 'MCP 管理',
ai_gpu_view: 'GPU 表示',
ai_benchmark_view: 'AI ベンチマーク表示',
ai_benchmark_manage: 'AI ベンチマーク管理',
website_view: 'サイト表示',
website_manage: 'サイト管理',
website_cert_view: '証明書表示',
+54
View File
@@ -26,6 +26,7 @@ const message = {
conn: '연결',
disConn: '연결 해제',
clean: '지우기',
cleanAll: '모두 지우기',
selectAll: '전체 선택',
login: '로그인',
close: '닫기',
@@ -975,6 +976,57 @@ const message = {
validationModelMapEmpty: '모델 매핑의 모델 이름은 비워 없습니다',
validationModelMapDuplicate: '요청 모델 {0}() 중복되었습니다',
},
benchmark: {
title: '벤치마크',
create: '생성',
launchCommand: '시작 명령',
retest: '다시 테스트',
statusRunning: '실행 ',
statusWaiting: '대기 ',
base: '기본 정보',
backend: '백엔드',
baseUrl: 'Base URL',
endpoint: '엔드포인트',
tokenizer: '토크나이저',
tokenizerPlaceholder:
'로컬 토크나이저 디렉터리를 선택하거나 입력하세요. : /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: '실행 구성',
rawResult: '원시 결과',
resultMetrics: '결과 지표',
contextTokens: '컨텍스트 길이',
contextTokensHelper: ' 벤치마크의 입력 Token 제한과 출력 Token 제한의 합계입니다.',
outputThroughput: '출력 처리량',
outputThroughputHelper: '초당 생성된 출력 Token 수입니다. 높을수록 생성 속도가 빠릅니다.',
totalThroughput: ' 처리량',
totalThroughputHelper: '초당 처리된 입력 출력 Token 수로 전체 처리 능력을 측정합니다.',
firstTokenLatency: ' Token 지연 시간',
firstTokenLatencyHelper: '요청 전송부터 Token 수신까지의 시간입니다. 낮을수록 응답이 빠릅니다.',
inputTokens: '입력 Token',
outputTokens: '출력 Token',
tokenValueHelper: '양의 정수 또는 k 값을 입력하세요. : 512, 1k, 32k',
numPrompts: '프롬프트 ',
concurrency: '동시성',
requestRate: '요청 속도',
requestRateUnlimited: '무제한(최대 처리량)',
requestRateCustom: '사용자 지정 QPS',
requestRateCustomPlaceholder: '초당 요청 , : 2.5',
successfulRequests: '성공한 요청',
failedRequests: '실패한 요청',
requestThroughput: '요청 처리량',
ttftMean: '평균 TTFT',
ttftMedian: '중앙값 TTFT',
ttftP99: 'P99 TTFT',
tpotMean: '평균 TPOT',
tpotMedian: '중앙값 TPOT',
tpotP99: 'P99 TPOT',
itlMean: '평균 ITL',
itlMedian: '중앙값 ITL',
itlP99: 'P99 ITL',
timeout: '시간 초과()',
image: 'vLLM 이미지',
ignoreEos: 'EOS 무시',
extraHeaders: '추가 헤더',
},
gpu: {
gpu: 'GPU 모니터링',
gpuHelper: '시스템에서 NVIDIA-SMI 또는 XPU-SMI 명령을 감지하지 못했습니다. 확인하고 다시 시도하세요!',
@@ -3722,6 +3774,8 @@ const message = {
ai_mcp_view: 'MCP 보기',
ai_mcp_manage: 'MCP 관리',
ai_gpu_view: 'GPU 보기',
ai_benchmark_view: 'AI 벤치마크 보기',
ai_benchmark_manage: 'AI 벤치마크 관리',
website_view: '웹사이트 보기',
website_manage: '웹사이트 관리',
website_cert_view: '인증서 보기',
+56
View File
@@ -26,6 +26,7 @@ const message = {
conn: 'Sambung',
disConn: 'Putus sambungan',
clean: 'Kosongkan',
cleanAll: 'Kosongkan semua',
selectAll: 'Pilih semua',
login: 'Log masuk',
close: 'Tutup',
@@ -1000,6 +1001,59 @@ const message = {
validationModelMapEmpty: 'Nama model dalam pemetaan model tidak boleh kosong',
validationModelMapDuplicate: 'Model permintaan {0} berulang',
},
benchmark: {
title: 'Penanda Aras',
create: 'Cipta',
launchCommand: 'Arahan Pelancaran',
retest: 'Uji Semula',
statusRunning: 'Sedang berjalan',
statusWaiting: 'Menunggu',
base: 'Maklumat Asas',
backend: 'Backend',
baseUrl: 'URL Asas',
endpoint: 'Endpoint',
tokenizer: 'Tokenizer',
tokenizerPlaceholder:
'Pilih atau masukkan direktori tokenizer tempatan, cth. /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: 'Konfigurasi Jalan',
rawResult: 'Keputusan Mentah',
resultMetrics: 'Metrik Keputusan',
contextTokens: 'Panjang Konteks',
contextTokensHelper: 'Had token input ditambah had token output untuk penanda aras ini.',
outputThroughput: 'Throughput Output',
outputThroughputHelper: 'Token output dijana setiap saat. Lebih tinggi bermaksud penjanaan lebih pantas.',
totalThroughput: 'Jumlah Throughput',
totalThroughputHelper:
'Token input dan output diproses setiap saat. Digunakan untuk mengukur kapasiti keseluruhan.',
firstTokenLatency: 'Latensi Token Pertama',
firstTokenLatencyHelper:
'Masa dari menghantar permintaan hingga menerima token pertama. Lebih rendah bermaksud respons lebih pantas.',
inputTokens: 'Token Input',
outputTokens: 'Token Output',
tokenValueHelper: 'Masukkan integer positif atau nilai k, cth. 512, 1k, 32k',
numPrompts: 'Prompt',
concurrency: 'Keserentakan',
requestRate: 'Kadar Permintaan',
requestRateUnlimited: 'Tanpa had (throughput maksimum)',
requestRateCustom: 'QPS tersuai',
requestRateCustomPlaceholder: 'Permintaan sesaat, cth. 2.5',
successfulRequests: 'Permintaan berjaya',
failedRequests: 'Permintaan gagal',
requestThroughput: 'Throughput Permintaan',
ttftMean: 'Purata TTFT',
ttftMedian: 'Median TTFT',
ttftP99: 'P99 TTFT',
tpotMean: 'Purata TPOT',
tpotMedian: 'Median TPOT',
tpotP99: 'P99 TPOT',
itlMean: 'Purata ITL',
itlMedian: 'Median ITL',
itlP99: 'P99 ITL',
timeout: 'Tamat Masa (saat)',
image: 'Imej vLLM',
ignoreEos: 'Abaikan EOS',
extraHeaders: 'Pengepala Tambahan',
},
gpu: {
gpu: 'Pemantauan GPU',
gpuHelper: 'Sistem tidak mengesan arahan NVIDIA-SMI atau XPU-SMI. Sila periksa dan cuba lagi!',
@@ -3861,6 +3915,8 @@ const message = {
ai_mcp_view: 'Paparan MCP',
ai_mcp_manage: 'Pengurusan MCP',
ai_gpu_view: 'Paparan GPU',
ai_benchmark_view: 'Paparan Penanda Aras AI',
ai_benchmark_manage: 'Pengurusan Penanda Aras AI',
website_view: 'Paparan Laman Web',
website_manage: 'Pengurusan Laman Web',
website_cert_view: 'Paparan Sijil',
+56
View File
@@ -26,6 +26,7 @@ const message = {
conn: 'Conectar',
disConn: 'Desconectar',
clean: 'Limpar',
cleanAll: 'Limpar tudo',
selectAll: 'Selecionar tudo',
login: 'Entrar',
close: 'Fechar',
@@ -996,6 +997,59 @@ const message = {
validationModelMapEmpty: 'Os nomes no mapeamento de modelos não podem ficar vazios',
validationModelMapDuplicate: 'O modelo solicitado {0} está duplicado',
},
benchmark: {
title: 'Benchmark',
create: 'Criar',
launchCommand: 'Comando de inicialização',
retest: 'Testar novamente',
statusRunning: 'Executando',
statusWaiting: 'Aguardando',
base: 'Informações básicas',
backend: 'Backend',
baseUrl: 'URL base',
endpoint: 'Endpoint',
tokenizer: 'Tokenizer',
tokenizerPlaceholder:
'Selecione ou informe um diretório local de tokenizer, ex.: /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: 'Configuração de execução',
rawResult: 'Resultado bruto',
resultMetrics: 'Métricas de resultado',
contextTokens: 'Comprimento de contexto',
contextTokensHelper: 'Limite de tokens de entrada mais limite de tokens de saída para este benchmark.',
outputThroughput: 'Throughput de saída',
outputThroughputHelper: 'Tokens de saída gerados por segundo. Quanto maior, mais rápida a geração.',
totalThroughput: 'Throughput total',
totalThroughputHelper:
'Tokens de entrada e saída processados por segundo. Usado para medir a capacidade geral.',
firstTokenLatency: 'Latência do primeiro token',
firstTokenLatencyHelper:
'Tempo entre enviar a requisição e receber o primeiro token. Quanto menor, mais rápida a resposta.',
inputTokens: 'Tokens de entrada',
outputTokens: 'Tokens de saída',
tokenValueHelper: 'Informe um inteiro positivo ou valor com k, ex.: 512, 1k, 32k',
numPrompts: 'Prompts',
concurrency: 'Concorrência',
requestRate: 'Taxa de requisições',
requestRateUnlimited: 'Ilimitado (throughput máximo)',
requestRateCustom: 'QPS personalizado',
requestRateCustomPlaceholder: 'Requisições por segundo, ex.: 2.5',
successfulRequests: 'Requisições bem-sucedidas',
failedRequests: 'Requisições com falha',
requestThroughput: 'Throughput de requisições',
ttftMean: 'TTFT médio',
ttftMedian: 'TTFT mediano',
ttftP99: 'TTFT P99',
tpotMean: 'TPOT médio',
tpotMedian: 'TPOT mediano',
tpotP99: 'TPOT P99',
itlMean: 'ITL médio',
itlMedian: 'ITL mediano',
itlP99: 'ITL P99',
timeout: 'Timeout (segundos)',
image: 'Imagem vLLM',
ignoreEos: 'Ignorar EOS',
extraHeaders: 'Cabeçalhos extras',
},
gpu: {
gpu: 'Monitoramento de GPU',
gpuHelper: 'O sistema não detectou comandos NVIDIA-SMI ou XPU-SMI. Verifique e tente novamente!',
@@ -4000,6 +4054,8 @@ const message = {
ai_mcp_view: 'Visualização do MCP',
ai_mcp_manage: 'Gerenciamento do MCP',
ai_gpu_view: 'Visualização da GPU',
ai_benchmark_view: 'Visualização do Benchmark de IA',
ai_benchmark_manage: 'Gerenciamento do Benchmark de IA',
website_view: 'Visualização do Site',
website_manage: 'Gerenciamento do Site',
website_cert_view: 'Visualização do Certificado',
+57
View File
@@ -26,6 +26,7 @@ const message = {
conn: 'Подключить',
disConn: 'Отключить',
clean: 'Очистить',
cleanAll: 'Очистить все',
selectAll: 'Выбрать все',
login: 'Войти',
close: 'Закрыть',
@@ -990,6 +991,60 @@ const message = {
validationModelMapEmpty: 'Имена моделей в сопоставлении не могут быть пустыми',
validationModelMapDuplicate: 'Запрошенная модель {0} дублируется',
},
benchmark: {
title: 'Бенчмарк',
create: 'Создать',
launchCommand: 'Команда запуска',
retest: 'Повторить тест',
statusRunning: 'Выполняется',
statusWaiting: 'Ожидание',
base: 'Основная информация',
backend: 'Backend',
baseUrl: 'Base URL',
endpoint: 'Endpoint',
tokenizer: 'Токенизатор',
tokenizerPlaceholder:
'Выберите или введите локальный каталог токенизатора, например /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: 'Конфигурация запуска',
rawResult: 'Исходный результат',
resultMetrics: 'Метрики результата',
contextTokens: 'Длина контекста',
contextTokensHelper: 'Лимит входных токенов плюс лимит выходных токенов для этого бенчмарка.',
outputThroughput: 'Выходная пропускная способность',
outputThroughputHelper:
'Выходные токены, генерируемые в секунду. Чем выше значение, тем быстрее генерация.',
totalThroughput: 'Общая пропускная способность',
totalThroughputHelper:
'Входные и выходные токены, обработанные в секунду. Используется для оценки общей емкости.',
firstTokenLatency: 'Задержка первого токена',
firstTokenLatencyHelper:
'Время от отправки запроса до получения первого токена. Чем ниже значение, тем быстрее ответ.',
inputTokens: 'Входные токены',
outputTokens: 'Выходные токены',
tokenValueHelper: 'Введите положительное целое число или значение с k, например 512, 1k, 32k',
numPrompts: 'Промпты',
concurrency: 'Параллелизм',
requestRate: 'Частота запросов',
requestRateUnlimited: 'Без ограничений (макс. пропускная способность)',
requestRateCustom: 'Пользовательский QPS',
requestRateCustomPlaceholder: 'Запросов в секунду, например 2.5',
successfulRequests: 'Успешные запросы',
failedRequests: 'Неуспешные запросы',
requestThroughput: 'Пропускная способность запросов',
ttftMean: 'Средний TTFT',
ttftMedian: 'Медианный TTFT',
ttftP99: 'P99 TTFT',
tpotMean: 'Средний TPOT',
tpotMedian: 'Медианный TPOT',
tpotP99: 'P99 TPOT',
itlMean: 'Средний ITL',
itlMedian: 'Медианный ITL',
itlP99: 'P99 ITL',
timeout: 'Тайм-аут (секунды)',
image: 'Образ vLLM',
ignoreEos: 'Игнорировать EOS',
extraHeaders: 'Дополнительные заголовки',
},
gpu: {
gpu: 'Мониторинг GPU',
gpuHelper: 'Система не обнаружила команды NVIDIA-SMI или XPU-SMI. Проверьте и повторите попытку!',
@@ -3854,6 +3909,8 @@ const message = {
ai_mcp_view: 'Просмотр MCP',
ai_mcp_manage: 'Управление MCP',
ai_gpu_view: 'Просмотр GPU',
ai_benchmark_view: 'Просмотр AI-бенчмарка',
ai_benchmark_manage: 'Управление AI-бенчмарком',
website_view: 'Просмотр сайта',
website_manage: 'Управление сайтом',
website_cert_view: 'Просмотр сертификата',
+56
View File
@@ -29,6 +29,7 @@ const message = {
conn: 'Bağlan',
disconn: 'Bağlantıyı Kes',
clean: 'Temizle',
cleanAll: 'Tümünü temizle',
selectAll: 'Tümünü seç',
login: 'Oturum ',
close: 'Kapat',
@@ -998,6 +999,59 @@ const message = {
validationModelMapEmpty: 'Model eşlemesindeki model adları boş olamaz',
validationModelMapDuplicate: 'İstek modeli {0} yineleniyor',
},
benchmark: {
title: 'Benchmark',
create: 'Oluştur',
launchCommand: 'Başlatma Komutu',
retest: 'Yeniden test et',
statusRunning: 'Çalışıyor',
statusWaiting: 'Bekliyor',
base: 'Temel Bilgiler',
backend: 'Backend',
baseUrl: 'Base URL',
endpoint: 'Endpoint',
tokenizer: 'Tokenizer',
tokenizerPlaceholder: 'Yerel tokenizer dizini seçin veya girin, örn. /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: 'Çalıştırma Yapılandırması',
rawResult: 'Ham Sonuç',
resultMetrics: 'Sonuç Metrikleri',
contextTokens: 'Bağlam Uzunluğu',
contextTokensHelper: 'Bu benchmark için giriş token sınırı ile çıkış token sınırının toplamı.',
outputThroughput: 'Çıkış Throughput',
outputThroughputHelper:
'Saniye başına üretilen çıkış token sayısı. Daha yüksek değer daha hızlı üretimdir.',
totalThroughput: 'Toplam Throughput',
totalThroughputHelper:
'Saniye başına işlenen giriş ve çıkış token sayısı. Genel kapasiteyi ölçmek için kullanılır.',
firstTokenLatency: 'İlk Token Gecikmesi',
firstTokenLatencyHelper:
'İsteğin gönderilmesinden ilk token alınana kadar geçen süre. Daha düşük değer daha hızlı yanıttır.',
inputTokens: 'Giriş Token',
outputTokens: 'Çıkış Token',
tokenValueHelper: 'Pozitif tam sayı veya k değeri girin, örn. 512, 1k, 32k',
numPrompts: 'Prompt',
concurrency: 'Eşzamanlılık',
requestRate: 'İstek Hızı',
requestRateUnlimited: 'Sınırsız (maksimum throughput)',
requestRateCustom: 'Özel QPS',
requestRateCustomPlaceholder: 'Saniye başına istek, örn. 2.5',
successfulRequests: 'Başarılı istekler',
failedRequests: 'Başarısız istekler',
requestThroughput: 'İstek Throughput',
ttftMean: 'Ortalama TTFT',
ttftMedian: 'Medyan TTFT',
ttftP99: 'P99 TTFT',
tpotMean: 'Ortalama TPOT',
tpotMedian: 'Medyan TPOT',
tpotP99: 'P99 TPOT',
itlMean: 'Ortalama ITL',
itlMedian: 'Medyan ITL',
itlP99: 'P99 ITL',
timeout: 'Zaman aşımı (saniye)',
image: 'vLLM İmajı',
ignoreEos: "EOS'u yok say",
extraHeaders: 'Ek Başlıklar',
},
gpu: {
gpu: 'GPU İzleme',
gpuHelper: 'Sistem NVIDIA-SMI veya XPU-SMI komutlarını algılamadı. Lütfen kontrol edip tekrar deneyin!',
@@ -3854,6 +3908,8 @@ const message = {
ai_mcp_view: 'MCP Görünümü',
ai_mcp_manage: 'MCP Yönetimi',
ai_gpu_view: 'GPU Görünümü',
ai_benchmark_view: 'AI Benchmark Görünümü',
ai_benchmark_manage: 'AI Benchmark Yönetimi',
website_view: 'Web Sitesi Görünümü',
website_manage: 'Web Sitesi Yönetimi',
website_cert_view: 'Sertifika Görünümü',
+53
View File
@@ -29,6 +29,7 @@ const message = {
conn: '連接',
disConn: '斷開',
clean: '清除',
cleanAll: '清空所有',
selectAll: '全選',
login: '登入',
close: '關閉',
@@ -935,6 +936,56 @@ const message = {
validationModelMapEmpty: '模型映射的模型名稱不能為空',
validationModelMapDuplicate: '請求模型 {0} 重複',
},
benchmark: {
title: '基準測試',
create: '建立',
launchCommand: '啟動命令',
retest: '重新測試',
statusRunning: '執行中',
statusWaiting: '等待中',
base: '基礎資訊',
backend: '後端',
baseUrl: '服務地址',
endpoint: '介面路徑',
tokenizer: '分詞器',
tokenizerPlaceholder: '請選擇或輸入本機分詞器目錄,例如 /opt/1panel/tokenizers/DeepSeek-V3',
runConfig: '執行設定',
rawResult: '原始結果',
resultMetrics: '結果指標',
contextTokens: '上下文長度',
contextTokensHelper: '本次測試的輸入 Token 與輸出 Token 上限之和。',
outputThroughput: '輸出吞吐',
outputThroughputHelper: '模型每秒產生的輸出 Token 數,越高表示生成速度越快。',
totalThroughput: '總吞吐',
totalThroughputHelper: '每秒處理的輸入與輸出 Token 總數,用於衡量整體處理能力。',
firstTokenLatency: '首 Token 延遲',
firstTokenLatencyHelper: '從請求送出到收到第一個 Token 的時間,越低表示回應越快。',
inputTokens: '輸入 Token',
outputTokens: '輸出 Token',
tokenValueHelper: '請輸入正整數或 k 單位,例如 512、1k、32k',
numPrompts: '請求數量',
concurrency: '併發數',
requestRate: '請求速率',
requestRateUnlimited: '不限速(最大吞吐)',
requestRateCustom: '自訂 QPS',
requestRateCustomPlaceholder: '請輸入每秒請求數,如 2.5',
successfulRequests: '成功請求',
failedRequests: '失敗請求',
requestThroughput: '請求吞吐',
ttftMean: 'TTFT 平均',
ttftMedian: 'TTFT 中位數',
ttftP99: 'TTFT P99',
tpotMean: 'TPOT 平均',
tpotMedian: 'TPOT 中位數',
tpotP99: 'TPOT P99',
itlMean: 'ITL 平均',
itlMedian: 'ITL 中位數',
itlP99: 'ITL P99',
timeout: '逾時時間(秒)',
image: 'vLLM 映像',
ignoreEos: '忽略 EOS',
extraHeaders: '額外請求標頭',
},
gpu: {
gpu: 'GPU 監控',
gpuHelper: '目前系統未偵測到 NVIDIA-SMI 或 XPU-SMI 指令,請檢查後重試',
@@ -3503,6 +3554,8 @@ const message = {
ai_mcp_view: 'MCP 檢視',
ai_mcp_manage: 'MCP 管理',
ai_gpu_view: 'GPU 檢視',
ai_benchmark_view: 'AI 基準測試檢視',
ai_benchmark_manage: 'AI 基準測試管理',
website_view: '網站檢視',
website_manage: '網站管理',
website_cert_view: '憑證檢視',
+3
View File
@@ -29,6 +29,7 @@ const message = {
conn: '连接',
disConn: '断开',
clean: '清空',
cleanAll: '清空所有',
selectAll: '全选',
login: '登录',
close: '关闭',
@@ -4148,6 +4149,8 @@ const message = {
ai_mcp_view: 'MCP 查看',
ai_mcp_manage: 'MCP 管理',
ai_gpu_view: 'GPU 查看',
ai_benchmark_view: 'AI 基准测试查看',
ai_benchmark_manage: 'AI 基准测试管理',
website_view: '网站查看',
website_manage: '网站管理',
website_cert_view: '证书查看',
@@ -144,7 +144,7 @@ import { getAppService } from '@/api/modules/app';
import { Rules } from '@/global/form-rules';
import { App } from '@/api/interface/app';
import { getDBName, getLabel, getDescription } from '@/utils/app-store';
import { getPathByType } from '@/api/modules/files';
import { loadWebsiteDir } from '@/api/modules/setting';
import { loadFormatCollations } from '@/api/modules/database';
interface ParamObj extends App.FromField {
@@ -226,7 +226,7 @@ const handleParams = () => {
form[p.envKey] = p.default;
}
if (p.type == 'text' && p.envKey == 'WEBSITE_DIR') {
getPathByType('websiteDir').then((res) => {
loadWebsiteDir().then((res) => {
form[p.envKey] = res.data;
});
}
+2 -2
View File
@@ -10,7 +10,7 @@
>
<template #route-button>
<div class="router-button" v-if="!isOffline">
<template v-if="!isProductPro">
<template v-if="!isProductPro && !isEnterprise">
<el-button link type="primary" @click="toUpload">
{{ $t('license.levelUpPro') }}
</el-button>
@@ -539,7 +539,7 @@ const ioOptionsFromCache = ref(false);
const hasRefreshedOptionsOnHover = ref(false);
const quickJumpRef = ref();
const { isProductPro, isOffline } = storeToRefs(globalStore);
const { isProductPro, isEnterprise, isOffline } = storeToRefs(globalStore);
const searchInfo = reactive({
ioOption: 'all',
@@ -458,7 +458,7 @@ import { getAppService } from '@/api/modules/app';
import { v4 as uuidv4 } from 'uuid';
import { getAccountName } from '@/utils/ssl';
import { Website } from '@/api/interface/website';
import { getPathByType } from '@/api/modules/files';
import { loadWebsiteDir } from '@/api/modules/setting';
import { getWebsiteTypes } from '@/global/mimetype';
import { compareVersion } from '@/utils/version';
defineOptions({ name: 'CreateWebSite' });
@@ -784,7 +784,7 @@ const acceptParams = async (openrestyVersion: string) => {
}
const websiteType = localStorage.getItem('website-type') || 'deployment';
website.value.type = websiteType;
const dirRes = await getPathByType('websiteDir');
const dirRes = await loadWebsiteDir();
staticPath.value = dirRes.data + '/sites/';
changeType(websiteType);