mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-10 16:00:31 +00:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d674f14ad | ||
|
|
b772effacd | ||
|
|
2417cc9eed | ||
|
|
c0796dc7c4 | ||
|
|
ff9747560e | ||
|
|
9c2828385b | ||
|
|
ad5df58d0f | ||
|
|
bb5e0f98c2 | ||
|
|
bfa2eb43ea | ||
|
|
be27983938 | ||
|
|
7ff1819799 | ||
|
|
7ff39c91da |
@@ -14,6 +14,8 @@ type TensorRTLLMCreate struct {
|
|||||||
ModelDir string `json:"modelDir" validate:"required"`
|
ModelDir string `json:"modelDir" validate:"required"`
|
||||||
Image string `json:"image" validate:"required"`
|
Image string `json:"image" validate:"required"`
|
||||||
Command string `json:"command" validate:"required"`
|
Command string `json:"command" validate:"required"`
|
||||||
|
ModelType string `json:"modelType"`
|
||||||
|
ModelSpeedup bool `json:"modelSpeedup"`
|
||||||
DockerConfig
|
DockerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ type Cronjob struct {
|
|||||||
EntryIDs string `json:"entryIDs"`
|
EntryIDs string `json:"entryIDs"`
|
||||||
Records []JobRecords `json:"records"`
|
Records []JobRecords `json:"records"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
|
|
||||||
|
Config string `json:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type JobRecords struct {
|
type JobRecords struct {
|
||||||
|
|||||||
@@ -3,13 +3,17 @@ package model
|
|||||||
type MonitorBase struct {
|
type MonitorBase struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Cpu float64 `json:"cpu"`
|
Cpu float64 `json:"cpu"`
|
||||||
|
TopCPU string `json:"topCPU"`
|
||||||
|
TopCPUItems interface{} `gorm:"-" json:"topCPUItems"`
|
||||||
|
|
||||||
|
Memory float64 `json:"memory"`
|
||||||
|
TopMem string `json:"topMem"`
|
||||||
|
TopMemItems interface{} `gorm:"-" json:"topMemItems"`
|
||||||
|
|
||||||
LoadUsage float64 `json:"loadUsage"`
|
LoadUsage float64 `json:"loadUsage"`
|
||||||
CpuLoad1 float64 `json:"cpuLoad1"`
|
CpuLoad1 float64 `json:"cpuLoad1"`
|
||||||
CpuLoad5 float64 `json:"cpuLoad5"`
|
CpuLoad5 float64 `json:"cpuLoad5"`
|
||||||
CpuLoad15 float64 `json:"cpuLoad15"`
|
CpuLoad15 float64 `json:"cpuLoad15"`
|
||||||
|
|
||||||
Memory float64 `json:"memory"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MonitorIO struct {
|
type MonitorIO struct {
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ type TensorRTLLM struct {
|
|||||||
DockerCompose string `json:"dockerCompose"`
|
DockerCompose string `json:"dockerCompose"`
|
||||||
ContainerName string `json:"containerName"`
|
ContainerName string `json:"containerName"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
//Port int `json:"port"`
|
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Env string `json:"env"`
|
Env string `json:"env"`
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
|
ModelType string `json:"modelType"`
|
||||||
|
ModelSpeedup bool `json:"modelSpeedup"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
||||||
@@ -12,10 +13,13 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/agent/global"
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/compose"
|
"github.com/1Panel-dev/1Panel/agent/utils/compose"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/env"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||||
"github.com/subosito/gotenv"
|
"github.com/subosito/gotenv"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -52,7 +56,7 @@ func (t TensorRTLLMService) Page(req request.TensorRTLLMSearch) response.TensorR
|
|||||||
serverDTO.ModelDir = envs["MODEL_PATH"]
|
serverDTO.ModelDir = envs["MODEL_PATH"]
|
||||||
serverDTO.Dir = path.Join(global.Dir.TensorRTLLMDir, item.Name)
|
serverDTO.Dir = path.Join(global.Dir.TensorRTLLMDir, item.Name)
|
||||||
serverDTO.Image = envs["IMAGE"]
|
serverDTO.Image = envs["IMAGE"]
|
||||||
serverDTO.Command = envs["COMMAND"]
|
serverDTO.Command = getCommand(item.Env)
|
||||||
|
|
||||||
for k, v := range envs {
|
for k, v := range envs {
|
||||||
if strings.Contains(k, "CONTAINER_PORT") || strings.Contains(k, "HOST_PORT") {
|
if strings.Contains(k, "CONTAINER_PORT") || strings.Contains(k, "HOST_PORT") {
|
||||||
@@ -81,20 +85,13 @@ func (t TensorRTLLMService) Page(req request.TensorRTLLMSearch) response.TensorR
|
|||||||
}
|
}
|
||||||
|
|
||||||
composeByte, err := files.NewFileOp().GetContent(path.Join(global.Dir.TensorRTLLMDir, item.Name, "docker-compose.yml"))
|
composeByte, err := files.NewFileOp().GetContent(path.Join(global.Dir.TensorRTLLMDir, item.Name, "docker-compose.yml"))
|
||||||
if err != nil {
|
if err == nil {
|
||||||
continue
|
serverDTO.Environments, _ = getDockerComposeEnvironments(composeByte)
|
||||||
}
|
|
||||||
serverDTO.Environments, err = getDockerComposeEnvironments(composeByte)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
volumes, err := getDockerComposeVolumes(composeByte)
|
volumes, err := getDockerComposeVolumes(composeByte)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultVolumes = map[string]string{
|
var defaultVolumes = map[string]string{
|
||||||
"${MODEL_PATH}": "/models",
|
"${MODEL_PATH}": "${MODEL_PATH}",
|
||||||
}
|
}
|
||||||
for _, volume := range volumes {
|
for _, volume := range volumes {
|
||||||
exist := false
|
exist := false
|
||||||
@@ -108,6 +105,7 @@ func (t TensorRTLLMService) Page(req request.TensorRTLLMSearch) response.TensorR
|
|||||||
serverDTO.Volumes = append(serverDTO.Volumes, volume)
|
serverDTO.Volumes = append(serverDTO.Volumes, volume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
items = append(items, serverDTO)
|
items = append(items, serverDTO)
|
||||||
}
|
}
|
||||||
res.Total = total
|
res.Total = total
|
||||||
@@ -159,16 +157,15 @@ func handleLLMParams(llm *model.TensorRTLLM, create request.TensorRTLLMCreate) e
|
|||||||
|
|
||||||
delete(serviceValue, "environment")
|
delete(serviceValue, "environment")
|
||||||
var environments []interface{}
|
var environments []interface{}
|
||||||
|
environments = append(environments, fmt.Sprintf("MODEL_PATH=%s", create.ModelDir))
|
||||||
for _, e := range create.Environments {
|
for _, e := range create.Environments {
|
||||||
environments = append(environments, fmt.Sprintf("%s=%s", e.Key, e.Value))
|
environments = append(environments, fmt.Sprintf("%s=%s", e.Key, e.Value))
|
||||||
}
|
}
|
||||||
if len(environments) > 0 {
|
|
||||||
serviceValue["environment"] = environments
|
serviceValue["environment"] = environments
|
||||||
}
|
|
||||||
|
|
||||||
var volumes []interface{}
|
var volumes []interface{}
|
||||||
var defaultVolumes = map[string]string{
|
var defaultVolumes = map[string]string{
|
||||||
"${MODEL_PATH}": "/models",
|
"${MODEL_PATH}": "${MODEL_PATH}",
|
||||||
}
|
}
|
||||||
for k, v := range defaultVolumes {
|
for k, v := range defaultVolumes {
|
||||||
volumes = append(volumes, fmt.Sprintf("%s:%s", k, v))
|
volumes = append(volumes, fmt.Sprintf("%s:%s", k, v))
|
||||||
@@ -188,23 +185,24 @@ func handleLLMParams(llm *model.TensorRTLLM, create request.TensorRTLLMCreate) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleLLMEnv(llm *model.TensorRTLLM, create request.TensorRTLLMCreate) gotenv.Env {
|
func handleLLMEnv(llm *model.TensorRTLLM, create request.TensorRTLLMCreate) gotenv.Env {
|
||||||
env := make(gotenv.Env)
|
envMap := make(gotenv.Env)
|
||||||
env["CONTAINER_NAME"] = create.ContainerName
|
envMap["CONTAINER_NAME"] = create.ContainerName
|
||||||
env["MODEL_PATH"] = create.ModelDir
|
envMap["MODEL_PATH"] = create.ModelDir
|
||||||
env["VERSION"] = create.Version
|
envMap["VERSION"] = create.Version
|
||||||
env["IMAGE"] = create.Image
|
envMap["IMAGE"] = create.Image
|
||||||
env["COMMAND"] = create.Command
|
envMap["COMMAND"] = create.Command
|
||||||
for i, port := range create.ExposedPorts {
|
for i, port := range create.ExposedPorts {
|
||||||
containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i)
|
containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i)
|
||||||
hostPortStr := fmt.Sprintf("HOST_PORT_%d", i)
|
hostPortStr := fmt.Sprintf("HOST_PORT_%d", i)
|
||||||
hostIPStr := fmt.Sprintf("HOST_IP_%d", i)
|
hostIPStr := fmt.Sprintf("HOST_IP_%d", i)
|
||||||
env[containerPortStr] = strconv.Itoa(port.ContainerPort)
|
envMap[containerPortStr] = strconv.Itoa(port.ContainerPort)
|
||||||
env[hostPortStr] = strconv.Itoa(port.HostPort)
|
envMap[hostPortStr] = strconv.Itoa(port.HostPort)
|
||||||
env[hostIPStr] = port.HostIP
|
envMap[hostIPStr] = port.HostIP
|
||||||
}
|
}
|
||||||
envStr, _ := gotenv.Marshal(env)
|
orders := []string{"MODEL_PATH", "COMMAND"}
|
||||||
|
envStr, _ := env.MarshalWithOrder(envMap, orders)
|
||||||
llm.Env = envStr
|
llm.Env = envStr
|
||||||
return env
|
return envMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t TensorRTLLMService) Create(create request.TensorRTLLMCreate) error {
|
func (t TensorRTLLMService) Create(create request.TensorRTLLMCreate) error {
|
||||||
@@ -227,27 +225,34 @@ func (t TensorRTLLMService) Create(create request.TensorRTLLMCreate) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tensorrtLLMDir := path.Join(global.Dir.TensorRTLLMDir, create.Name)
|
tensorrtLLMDir := path.Join(global.Dir.TensorRTLLMDir, create.Name)
|
||||||
filesOP := files.NewFileOp()
|
filesOp := files.NewFileOp()
|
||||||
if !filesOP.Stat(tensorrtLLMDir) {
|
if !filesOp.Stat(tensorrtLLMDir) {
|
||||||
_ = filesOP.CreateDir(tensorrtLLMDir, 0644)
|
_ = filesOp.CreateDir(tensorrtLLMDir, 0644)
|
||||||
|
}
|
||||||
|
if create.ModelSpeedup {
|
||||||
|
if err := handleModelArchive(create.ModelType, create.ModelDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tensorrtLLM := &model.TensorRTLLM{
|
tensorrtLLM := &model.TensorRTLLM{
|
||||||
Name: create.Name,
|
Name: create.Name,
|
||||||
ContainerName: create.ContainerName,
|
ContainerName: create.ContainerName,
|
||||||
Status: constant.StatusStarting,
|
Status: constant.StatusStarting,
|
||||||
|
ModelType: create.ModelType,
|
||||||
|
ModelSpeedup: create.ModelSpeedup,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := handleLLMParams(tensorrtLLM, create); err != nil {
|
if err := handleLLMParams(tensorrtLLM, create); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
env := handleLLMEnv(tensorrtLLM, create)
|
envMap := handleLLMEnv(tensorrtLLM, create)
|
||||||
llmDir := path.Join(global.Dir.TensorRTLLMDir, create.Name)
|
llmDir := path.Join(global.Dir.TensorRTLLMDir, create.Name)
|
||||||
envPath := path.Join(llmDir, ".env")
|
envPath := path.Join(llmDir, ".env")
|
||||||
if err := gotenv.Write(env, envPath); err != nil {
|
if err := env.WriteWithOrder(envMap, envPath, []string{"MODEL_PATH", "COMMAND"}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dockerComposePath := path.Join(llmDir, "docker-compose.yml")
|
dockerComposePath := path.Join(llmDir, "docker-compose.yml")
|
||||||
if err := filesOP.SaveFile(dockerComposePath, tensorrtLLM.DockerCompose, 0644); err != nil {
|
if err := filesOp.SaveFile(dockerComposePath, tensorrtLLM.DockerCompose, 0644); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tensorrtLLM.Status = constant.StatusStarting
|
tensorrtLLM.Status = constant.StatusStarting
|
||||||
@@ -269,18 +274,20 @@ func (t TensorRTLLMService) Update(req request.TensorRTLLMUpdate) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tensorrtLLM.ModelType = req.ModelType
|
||||||
|
tensorrtLLM.ModelSpeedup = req.ModelSpeedup
|
||||||
tensorrtLLM.ContainerName = req.ContainerName
|
tensorrtLLM.ContainerName = req.ContainerName
|
||||||
|
|
||||||
if err := handleLLMParams(tensorrtLLM, req.TensorRTLLMCreate); err != nil {
|
if err := handleLLMParams(tensorrtLLM, req.TensorRTLLMCreate); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
env := handleLLMEnv(tensorrtLLM, req.TensorRTLLMCreate)
|
envMap := handleLLMEnv(tensorrtLLM, req.TensorRTLLMCreate)
|
||||||
envStr, _ := gotenv.Marshal(env)
|
envStr, _ := gotenv.Marshal(envMap)
|
||||||
tensorrtLLM.Env = envStr
|
tensorrtLLM.Env = envStr
|
||||||
llmDir := path.Join(global.Dir.TensorRTLLMDir, tensorrtLLM.Name)
|
llmDir := path.Join(global.Dir.TensorRTLLMDir, tensorrtLLM.Name)
|
||||||
envPath := path.Join(llmDir, ".env")
|
envPath := path.Join(llmDir, ".env")
|
||||||
if err := gotenv.Write(env, envPath); err != nil {
|
if err := env.WriteWithOrder(envMap, envPath, []string{"MODEL_PATH", "COMMAND"}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dockerComposePath := path.Join(llmDir, "docker-compose.yml")
|
dockerComposePath := path.Join(llmDir, "docker-compose.yml")
|
||||||
@@ -381,3 +388,51 @@ func syncTensorRTLLMContainerStatus(tensorrtLLM *model.TensorRTLLM) error {
|
|||||||
}
|
}
|
||||||
return tensorrtLLMRepo.Save(tensorrtLLM)
|
return tensorrtLLMRepo.Save(tensorrtLLM)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findModelArchive(modelType string) (string, error) {
|
||||||
|
const baseDir = "/home/models"
|
||||||
|
prefix := fmt.Sprintf("FusionXplay_%s_Accelerator", modelType)
|
||||||
|
|
||||||
|
entries, err := os.ReadDir(baseDir)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to read %s: %w", baseDir, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
if entry.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := entry.Name()
|
||||||
|
if strings.HasPrefix(name, prefix) && strings.HasSuffix(name, ".tar.gz") {
|
||||||
|
return filepath.Join(baseDir, name), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New(fmt.Sprintf("no FusionXplay_%s_Accelerator*.tar.gz found in /home/models", modelType))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleModelArchive(modelType string, modelDir string) error {
|
||||||
|
filePath, err := findModelArchive(modelType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fileOp := files.NewFileOp()
|
||||||
|
if err = fileOp.TarGzExtractPro(filePath, modelDir, ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = fileOp.ChmodR(path.Join(modelDir, "fusionxpark_accelerator"), 0755, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCommand(envStr string) string {
|
||||||
|
lines := strings.Split(envStr, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if strings.HasPrefix(line, "COMMAND=") {
|
||||||
|
return strings.TrimPrefix(line, "COMMAND=")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- 1panel-network
|
- 1panel-network
|
||||||
volumes:
|
volumes:
|
||||||
- ${MODEL_PATH}:/models
|
- ${MODEL_PATH}:${MODEL_PATH}
|
||||||
ipc: host
|
ipc: host
|
||||||
ulimits:
|
ulimits:
|
||||||
memlock:
|
memlock:
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ func InitAgentDB() {
|
|||||||
migrations.UpdateCronjobSpec,
|
migrations.UpdateCronjobSpec,
|
||||||
migrations.UpdateWebsiteSSLAddColumn,
|
migrations.UpdateWebsiteSSLAddColumn,
|
||||||
migrations.AddTensorRTLLMModel,
|
migrations.AddTensorRTLLMModel,
|
||||||
|
migrations.UpdateMonitorInterval,
|
||||||
|
migrations.AddMonitorProcess,
|
||||||
|
migrations.UpdateCronJob,
|
||||||
|
migrations.UpdateTensorrtLLM,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -634,3 +635,48 @@ var AddTensorRTLLMModel = &gormigrate.Migration{
|
|||||||
return tx.AutoMigrate(&model.TensorRTLLM{})
|
return tx.AutoMigrate(&model.TensorRTLLM{})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var UpdateMonitorInterval = &gormigrate.Migration{
|
||||||
|
ID: "20251026-update-monitor-interval",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
var monitorInterval model.Setting
|
||||||
|
if err := tx.Where("key = ?", "MonitorInterval").First(&monitorInterval).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
interval, _ := strconv.Atoi(monitorInterval.Value)
|
||||||
|
if interval == 0 {
|
||||||
|
interval = 300
|
||||||
|
}
|
||||||
|
if err := tx.Model(&model.Setting{}).
|
||||||
|
Where("key = ?", "MonitorInterval").
|
||||||
|
Updates(map[string]interface{}{"value": fmt.Sprintf("%v", interval*60)}).
|
||||||
|
Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Create(&model.Setting{Key: "DefaultIO", Value: "all"}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var AddMonitorProcess = &gormigrate.Migration{
|
||||||
|
ID: "20251202-add-monitor-process",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
return global.MonitorDB.AutoMigrate(&model.MonitorBase{})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var UpdateCronJob = &gormigrate.Migration{
|
||||||
|
ID: "20251202-update-cronjob",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
return tx.AutoMigrate(&model.Cronjob{})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var UpdateTensorrtLLM = &gormigrate.Migration{
|
||||||
|
ID: "20251110-update-tensorrt-llm",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
return tx.AutoMigrate(&model.TensorRTLLM{})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+57
-3
@@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Write(envMap map[string]string, filename string) error {
|
func Write(envMap map[string]string, filename string) error {
|
||||||
content, err := marshal(envMap)
|
content, err := Marshal(envMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,7 @@ func Write(envMap map[string]string, filename string) error {
|
|||||||
return file.Sync()
|
return file.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshal(envMap map[string]string) (string, error) {
|
func Marshal(envMap map[string]string) (string, error) {
|
||||||
lines := make([]string, 0, len(envMap))
|
lines := make([]string, 0, len(envMap))
|
||||||
for k, v := range envMap {
|
for k, v := range envMap {
|
||||||
if d, err := strconv.Atoi(v); err == nil && !isStartWithZero(v) {
|
if d, err := strconv.Atoi(v); err == nil && !isStartWithZero(v) {
|
||||||
@@ -37,10 +37,64 @@ func marshal(envMap map[string]string) (string, error) {
|
|||||||
lines = append(lines, fmt.Sprintf(`%s="%s"`, k, v))
|
lines = append(lines, fmt.Sprintf(`%s="%s"`, k, v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Strings(lines)
|
|
||||||
return strings.Join(lines, "\n"), nil
|
return strings.Join(lines, "\n"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WriteWithOrder(envMap map[string]string, filename string, orders []string) error {
|
||||||
|
content, err := MarshalWithOrder(envMap, orders)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
file, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
_, err = file.WriteString(content + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return file.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalWithOrder(envMap map[string]string, orders []string) (string, error) {
|
||||||
|
lines := make([]string, 0, len(envMap))
|
||||||
|
for _, k := range orders {
|
||||||
|
if v, ok := envMap[k]; ok {
|
||||||
|
lines = append(lines, formatEnvLine(k, v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extraKeys := make([]string, 0)
|
||||||
|
for k := range envMap {
|
||||||
|
found := false
|
||||||
|
for _, okk := range orders {
|
||||||
|
if k == okk {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
extraKeys = append(extraKeys, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(extraKeys)
|
||||||
|
for _, k := range extraKeys {
|
||||||
|
lines = append(lines, formatEnvLine(k, envMap[k]))
|
||||||
|
}
|
||||||
|
return strings.Join(lines, "\n"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatEnvLine(k, v string) string {
|
||||||
|
if d, err := strconv.Atoi(v); err == nil && !isStartWithZero(v) {
|
||||||
|
return fmt.Sprintf(`%s=%d`, k, d)
|
||||||
|
} else if hasEvenDoubleQuotes(v) {
|
||||||
|
return fmt.Sprintf(`%s='%s'`, k, v)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf(`%s="%s"`, k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GetEnvValueByKey(envPath, key string) (string, error) {
|
func GetEnvValueByKey(envPath, key string) (string, error) {
|
||||||
envMap, err := godotenv.Read(envPath)
|
envMap, err := godotenv.Read(envPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+2
-2
@@ -17,11 +17,11 @@ download_resources() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "1panel-core.service" ]; then
|
if [ ! -f "1panel-core.service" ]; then
|
||||||
wget https://github.com/1Panel-dev/installer/raw/v2/1panel-core.service
|
wget https://github.com/1Panel-dev/installer/raw/v2/initscript/1panel-core.service
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "1panel-agent.service" ]; then
|
if [ ! -f "1panel-agent.service" ]; then
|
||||||
wget https://github.com/1Panel-dev/installer/raw/v2/1panel-agent.service
|
wget https://github.com/1Panel-dev/installer/raw/v2/initscript/1panel-agent.service
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "lang" ]; then
|
if [ ! -d "lang" ]; then
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/core/app/api/v2/helper"
|
"github.com/1Panel-dev/1Panel/core/app/api/v2/helper"
|
||||||
"github.com/1Panel-dev/1Panel/core/app/dto"
|
"github.com/1Panel-dev/1Panel/core/app/dto"
|
||||||
@@ -125,6 +127,20 @@ func (b *BaseApi) GetResponsePage(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, pageCode)
|
helper.SuccessWithData(c, pageCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) GetWelcomePage(c *gin.Context) {
|
||||||
|
count, _, _ := logService.PageLoginLog(c, dto.SearchLgLogWithPage{PageInfo: dto.PageInfo{Page: 1, PageSize: 10}})
|
||||||
|
if count != 1 {
|
||||||
|
helper.Success(c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, err := os.ReadFile(path.Join(global.CONF.Base.InstallDir, "1panel/welcome/index.html"))
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, string(file))
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Auth
|
// @Tags Auth
|
||||||
// @Summary Get Setting For Login
|
// @Summary Get Setting For Login
|
||||||
// @Success 200 {object} dto.SystemSetting
|
// @Success 200 {object} dto.SystemSetting
|
||||||
|
|||||||
@@ -16,5 +16,6 @@ func (s *BaseRouter) InitRouter(Router *gin.RouterGroup) {
|
|||||||
baseRouter.POST("/login", baseApi.Login)
|
baseRouter.POST("/login", baseApi.Login)
|
||||||
baseRouter.POST("/logout", baseApi.LogOut)
|
baseRouter.POST("/logout", baseApi.LogOut)
|
||||||
baseRouter.GET("/setting", baseApi.GetLoginSetting)
|
baseRouter.GET("/setting", baseApi.GetLoginSetting)
|
||||||
|
baseRouter.GET("/welcome", baseApi.GetWelcomePage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/core/init/db"
|
"github.com/1Panel-dev/1Panel/core/init/db"
|
||||||
"github.com/1Panel-dev/1Panel/core/init/geo"
|
"github.com/1Panel-dev/1Panel/core/init/geo"
|
||||||
@@ -58,6 +59,10 @@ func Start() {
|
|||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: global.CONF.Conn.BindAddress + ":" + global.CONF.Conn.Port,
|
Addr: global.CONF.Conn.BindAddress + ":" + global.CONF.Conn.Port,
|
||||||
Handler: rootRouter,
|
Handler: rootRouter,
|
||||||
|
ReadHeaderTimeout: 5 * time.Second,
|
||||||
|
ReadTimeout: 600 * time.Second,
|
||||||
|
WriteTimeout: 600 * time.Second,
|
||||||
|
IdleTimeout: 240 * time.Second,
|
||||||
}
|
}
|
||||||
ln, err := net.Listen(tcpItem, server.Addr)
|
ln, err := net.Listen(tcpItem, server.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -20,3 +20,7 @@ export const logOutApi = () => {
|
|||||||
export const getLoginSetting = () => {
|
export const getLoginSetting = () => {
|
||||||
return http.get<Login.LoginSetting>('/core/auth/setting');
|
return http.get<Login.LoginSetting>('/core/auth/setting');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getWelcomePage = () => {
|
||||||
|
return http.get<string>('/core/auth/welcome');
|
||||||
|
};
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ const mobile = computed(() => {
|
|||||||
return globalStore.isMobile();
|
return globalStore.isMobile();
|
||||||
});
|
});
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const tableHeight = ref(0);
|
const tableHeight = ref<number | string>('');
|
||||||
const menuRef = ref<HTMLElement | null>(null);
|
const menuRef = ref<HTMLElement | null>(null);
|
||||||
const leftSelect = ref(false);
|
const leftSelect = ref(false);
|
||||||
|
|
||||||
|
|||||||
@@ -728,9 +728,11 @@ const message = {
|
|||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: 'Model Directory',
|
modelDir: 'Model Directory',
|
||||||
commandHelper:
|
commandHelper:
|
||||||
'After /models in the startup command, the model name needs to be completed; if external access is required, set the port in the command to be the same as the application port',
|
'If external access is needed, set the port in the command to be the same as the application port',
|
||||||
imageAlert:
|
imageAlert:
|
||||||
'Due to the large image size, it is recommended to manually download the image to the server before installation',
|
'Due to the large image size, it is recommended to manually download the image to the server before installation',
|
||||||
|
modelSpeedup: 'Enable model acceleration',
|
||||||
|
modelType: 'Model type',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -729,9 +729,11 @@ const message = {
|
|||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: 'Directorio del Modelo',
|
modelDir: 'Directorio del Modelo',
|
||||||
commandHelper:
|
commandHelper:
|
||||||
'Después de /models en el comando de inicio, se debe completar el nombre del modelo; si se requiere acceso externo, configure el puerto en el comando para que sea el mismo que el puerto de la aplicación',
|
'Si se necesita acceso externo, establezca el puerto en el comando para que sea el mismo que el puerto de la aplicación',
|
||||||
imageAlert:
|
imageAlert:
|
||||||
'Debido al gran tamaño de la imagen, se recomienda descargar manualmente la imagen al servidor antes de la instalación',
|
'Debido al gran tamaño de la imagen, se recomienda descargar manualmente la imagen al servidor antes de la instalación',
|
||||||
|
modelSpeedup: 'Habilitar aceleración de modelo',
|
||||||
|
modelType: 'Tipo de modelo',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -716,9 +716,11 @@ const message = {
|
|||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: 'モデルディレクトリ',
|
modelDir: 'モデルディレクトリ',
|
||||||
commandHelper:
|
commandHelper:
|
||||||
'起動コマンドの /models の後にはモデル名を補完する必要があります;外部アクセスが必要な場合は、コマンド内のポートをアプリケーションポートと同じに設定してください',
|
'外部アクセスが必要な場合は、コマンド内のポートをアプリケーションポートと同じに設定してください',
|
||||||
imageAlert:
|
imageAlert:
|
||||||
'イメージサイズが大きいため、インストール前にサーバーにイメージを手動でダウンロードすることをお勧めします',
|
'イメージサイズが大きいため、インストール前にサーバーにイメージを手動でダウンロードすることをお勧めします',
|
||||||
|
modelSpeedup: 'モデル加速を有効化',
|
||||||
|
modelType: 'モデルタイプ',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -711,9 +711,10 @@ const message = {
|
|||||||
tensorRT: {
|
tensorRT: {
|
||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: '모델 디렉토리',
|
modelDir: '모델 디렉토리',
|
||||||
commandHelper:
|
commandHelper: '외부 액세스가 필요한 경우 명령에서 포트를 애플리케이션 포트와 동일하게 설정하십시오',
|
||||||
'시작 명령의 /models 뒤에는 모델 이름을 완성해야 합니다; 외부 액세스가 필요한 경우 명령의 포트를 애플리케이션 포트와 동일하게 설정하세요',
|
|
||||||
imageAlert: '이미지 크기가 크므로 설치 전에 서버에 이미지를 수동으로 다운로드하는 것이 좋습니다',
|
imageAlert: '이미지 크기가 크므로 설치 전에 서버에 이미지를 수동으로 다운로드하는 것이 좋습니다',
|
||||||
|
modelSpeedup: '모델 가속 활성화',
|
||||||
|
modelType: '모델 유형',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -728,10 +728,11 @@ const message = {
|
|||||||
tensorRT: {
|
tensorRT: {
|
||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: 'Direktori Model',
|
modelDir: 'Direktori Model',
|
||||||
commandHelper:
|
commandHelper: 'Jika akses luar diperlukan, tetapkan port dalam arahan sama dengan port aplikasi',
|
||||||
'Selepas /models dalam arahan permulaan, nama model perlu dilengkapkan; jika akses luar diperlukan, tetapkan port dalam arahan sama dengan port aplikasi',
|
|
||||||
imageAlert:
|
imageAlert:
|
||||||
'Disebabkan saiz imej yang besar, disyorkan untuk memuat turun imej secara manual ke pelayan sebelum pemasangan',
|
'Disebabkan saiz imej yang besar, disyorkan untuk memuat turun imej secara manual ke pelayan sebelum pemasangan',
|
||||||
|
modelSpeedup: 'Dayakan pecutan model',
|
||||||
|
modelType: 'Jenis model',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -725,9 +725,11 @@ const message = {
|
|||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: 'Diretório do Modelo',
|
modelDir: 'Diretório do Modelo',
|
||||||
commandHelper:
|
commandHelper:
|
||||||
'Após /models no comando de inicialização, o nome do modelo precisa ser completado; se for necessário acesso externo, defina a porta no comando para ser a mesma que a porta do aplicativo',
|
'Se for necessário acesso externo, defina a porta no comando para ser a mesma que a porta do aplicativo',
|
||||||
imageAlert:
|
imageAlert:
|
||||||
'Devido ao grande tamanho da imagem, recomenda-se baixar manualmente a imagem para o servidor antes da instalação',
|
'Devido ao grande tamanho da imagem, recomenda-se baixar manualmente a imagem para o servidor antes da instalação',
|
||||||
|
modelSpeedup: 'Ativar aceleração de modelo',
|
||||||
|
modelType: 'Tipo de modelo',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -722,10 +722,11 @@ const message = {
|
|||||||
tensorRT: {
|
tensorRT: {
|
||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: 'Каталог модели',
|
modelDir: 'Каталог модели',
|
||||||
commandHelper:
|
commandHelper: 'Если требуется внешний доступ, установите порт в команде таким же, как порт приложения',
|
||||||
'После /models в команде запуска необходимо указать имя модели; если требуется внешний доступ, установите порт в команде таким же, как порт приложения',
|
|
||||||
imageAlert:
|
imageAlert:
|
||||||
'Из-за большого размера образа рекомендуется вручную загрузить образ на сервер перед установкой',
|
'Из-за большого размера образа рекомендуется вручную загрузить образ на сервер перед установкой',
|
||||||
|
modelSpeedup: 'Включить ускорение модели',
|
||||||
|
modelType: 'Тип модели',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -737,9 +737,11 @@ const message = {
|
|||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: 'Model Dizini',
|
modelDir: 'Model Dizini',
|
||||||
commandHelper:
|
commandHelper:
|
||||||
'Başlatma komutundaki /models sonrasında model adı tamamlanmalıdır; harici erişim gerekiyorsa, komuttaki bağlantı noktasını uygulama bağlantı noktasıyla aynı olacak şekilde ayarlayın',
|
'Harici erişim gerekiyorsa, komuttaki bağlantı noktasını uygulama bağlantı noktasıyla aynı olacak şekilde ayarlayın',
|
||||||
imageAlert:
|
imageAlert:
|
||||||
'Görüntü boyutu büyük olduğundan, kurulumdan önce görüntüyü sunucuya manuel olarak indirmeniz önerilir',
|
'Görüntü boyutu büyük olduğundan, kurulumdan önce görüntüyü sunucuya manuel olarak indirmeniz önerilir',
|
||||||
|
modelSpeedup: 'Model hızlandırmayı etkinleştir',
|
||||||
|
modelType: 'Model türü',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -700,8 +700,10 @@ const message = {
|
|||||||
tensorRT: {
|
tensorRT: {
|
||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: '模型目錄',
|
modelDir: '模型目錄',
|
||||||
commandHelper: '啟動指令中的 /models 後需補全模型名稱;若需外部訪問,請將指令中的埠設定為與應用埠相同',
|
commandHelper: '若需外部訪問,請將命令中的端口設置為與應用端口相同',
|
||||||
imageAlert: '由於鏡像較大,建議先手動將鏡像下載到伺服器後再進行安裝',
|
imageAlert: '由於鏡像較大,建議先手動將鏡像下載到伺服器後再進行安裝',
|
||||||
|
modelSpeedup: '啟用模型加速',
|
||||||
|
modelType: '模型類型',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -700,8 +700,10 @@ const message = {
|
|||||||
tensorRT: {
|
tensorRT: {
|
||||||
llm: 'TensorRT LLM',
|
llm: 'TensorRT LLM',
|
||||||
modelDir: '模型目录',
|
modelDir: '模型目录',
|
||||||
commandHelper: '启动命令中的 /models 后需补全模型名称;若需外部访问,请将命令中的端口设置为与应用端口相同',
|
commandHelper: '若需外部访问,请将命令中的端口设置为与应用端口相同',
|
||||||
imageAlert: '由于镜像较大,建议先手动将镜像下载到服务器后再进行安装',
|
imageAlert: '由于镜像较大,建议先手动将镜像下载到服务器后再进行安装',
|
||||||
|
modelSpeedup: '启用模型加速',
|
||||||
|
modelType: '模型类型',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ const buttons = [
|
|||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.start'),
|
label: i18n.global.t('commons.button.start'),
|
||||||
disabled: (row: AI.TensorRTLLM) => {
|
disabled: (row: AI.TensorRTLLM) => {
|
||||||
return row.status === 'running';
|
return row.status === 'Running';
|
||||||
},
|
},
|
||||||
click: (row: AI.TensorRTLLM) => {
|
click: (row: AI.TensorRTLLM) => {
|
||||||
operate(row, 'start');
|
operate(row, 'start');
|
||||||
@@ -201,7 +201,7 @@ const buttons = [
|
|||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.stop'),
|
label: i18n.global.t('commons.button.stop'),
|
||||||
disabled: (row: AI.TensorRTLLM) => {
|
disabled: (row: AI.TensorRTLLM) => {
|
||||||
return row.status !== 'running';
|
return row.status !== 'Running';
|
||||||
},
|
},
|
||||||
click: (row: AI.TensorRTLLM) => {
|
click: (row: AI.TensorRTLLM) => {
|
||||||
operate(row, 'stop');
|
operate(row, 'stop');
|
||||||
@@ -209,9 +209,6 @@ const buttons = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: i18n.global.t('commons.button.restart'),
|
label: i18n.global.t('commons.button.restart'),
|
||||||
disabled: (row: AI.TensorRTLLM) => {
|
|
||||||
return row.status !== 'running';
|
|
||||||
},
|
|
||||||
click: (row: AI.TensorRTLLM) => {
|
click: (row: AI.TensorRTLLM) => {
|
||||||
operate(row, 'restart');
|
operate(row, 'restart');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,20 @@
|
|||||||
<el-form-item :label="$t('app.version')" prop="version">
|
<el-form-item :label="$t('app.version')" prop="version">
|
||||||
<el-input v-model.trim="tensorRTLLM.version" />
|
<el-input v-model.trim="tensorRTLLM.version" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div v-if="isFxplay">
|
||||||
|
<el-form-item :label="$t('aiTools.tensorRT.modelSpeedup')" prop="modelSpeedup">
|
||||||
|
<el-switch v-model="tensorRTLLM.modelSpeedup" @change="changeModelSpeedup"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('aiTools.tensorRT.modelType')"
|
||||||
|
prop="modelType"
|
||||||
|
v-if="tensorRTLLM.modelSpeedup"
|
||||||
|
>
|
||||||
|
<el-select v-model="tensorRTLLM.modelType">
|
||||||
|
<el-option label="Qwen3" value="Qwen3" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
<el-form-item :label="$t('aiTools.tensorRT.modelDir')" prop="modelDir">
|
<el-form-item :label="$t('aiTools.tensorRT.modelDir')" prop="modelDir">
|
||||||
<el-input v-model="tensorRTLLM.modelDir">
|
<el-input v-model="tensorRTLLM.modelDir">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
@@ -62,6 +76,8 @@ import i18n from '@/lang';
|
|||||||
import { ElForm, FormInstance } from 'element-plus';
|
import { ElForm, FormInstance } from 'element-plus';
|
||||||
import { createTensorRTLLM, updateTensorRTLLM } from '@/api/modules/ai';
|
import { createTensorRTLLM, updateTensorRTLLM } from '@/api/modules/ai';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||||
|
const { isFxplay } = useGlobalStore();
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const mode = ref('create');
|
const mode = ref('create');
|
||||||
@@ -73,10 +89,12 @@ const newTensorRTLLM = () => {
|
|||||||
version: '1.2.0rc0',
|
version: '1.2.0rc0',
|
||||||
modelDir: '',
|
modelDir: '',
|
||||||
image: 'nvcr.io/nvidia/tensorrt-llm/release',
|
image: 'nvcr.io/nvidia/tensorrt-llm/release',
|
||||||
command: 'bash -c "trtllm-serve /models/ --host 0.0.0.0 --port 8000"',
|
command: 'bash -c "trtllm-serve ${MODEL_PATH} --host 0.0.0.0 --port 8000"',
|
||||||
exposedPorts: [],
|
exposedPorts: [],
|
||||||
environments: [],
|
environments: [],
|
||||||
volumes: [],
|
volumes: [],
|
||||||
|
modelSpeedup: false,
|
||||||
|
modelType: 'Qwen3',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
const modelDirRef = ref();
|
const modelDirRef = ref();
|
||||||
@@ -101,6 +119,7 @@ const openEdit = (rowData: any): void => {
|
|||||||
if (tensorRTLLM.value.exposedPorts == null) {
|
if (tensorRTLLM.value.exposedPorts == null) {
|
||||||
tensorRTLLM.value.exposedPorts = [];
|
tensorRTLLM.value.exposedPorts = [];
|
||||||
}
|
}
|
||||||
|
tensorRTLLM.value.command = rowData.command.slice(1, -1).replace(/^'|'$/g, '').replace(/\\"/g, '"');
|
||||||
drawerVisiable.value = true;
|
drawerVisiable.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,6 +131,15 @@ const getModelDir = (path: string) => {
|
|||||||
tensorRTLLM.value.modelDir = path;
|
tensorRTLLM.value.modelDir = path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const changeModelSpeedup = () => {
|
||||||
|
if (tensorRTLLM.value.modelSpeedup) {
|
||||||
|
tensorRTLLM.value.command =
|
||||||
|
'bash -c "${MODEL_PATH}/fusionxpark_accelerator --model_path ${MODEL_PATH} --host 0.0.0.0 --port 8000"';
|
||||||
|
} else {
|
||||||
|
tensorRTLLM.value.command = 'bash -c "trtllm-serve ${MODEL_PATH} --host 0.0.0.0 --port 8000"';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
name: [Rules.requiredInput],
|
name: [Rules.requiredInput],
|
||||||
version: [Rules.requiredInput],
|
version: [Rules.requiredInput],
|
||||||
@@ -119,6 +147,7 @@ const rules = reactive({
|
|||||||
containerName: [Rules.requiredInput],
|
containerName: [Rules.requiredInput],
|
||||||
image: [Rules.requiredInput],
|
image: [Rules.requiredInput],
|
||||||
command: [Rules.requiredInput],
|
command: [Rules.requiredInput],
|
||||||
|
modelType: [Rules.requiredSelect],
|
||||||
});
|
});
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
|
|||||||
@@ -302,6 +302,10 @@
|
|||||||
|
|
||||||
<LicenseImport ref="licenseRef" />
|
<LicenseImport ref="licenseRef" />
|
||||||
<QuickJump @search="onLoadBaseInfo(false, 'all')" ref="quickJumpRef" />
|
<QuickJump @search="onLoadBaseInfo(false, 'all')" ref="quickJumpRef" />
|
||||||
|
|
||||||
|
<DialogPro v-model="welcomeOpen" size="w-70" id="welcomeDialog">
|
||||||
|
<div ref="shadowContainer" />
|
||||||
|
</DialogPro>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -323,6 +327,7 @@ import { getSettingInfo, listAllSimpleNodes, loadUpgradeInfo } from '@/api/modul
|
|||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore } from '@/store';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { routerToFileWithPath, routerToPath } from '@/utils/router';
|
import { routerToFileWithPath, routerToPath } from '@/utils/router';
|
||||||
|
import { getWelcomePage } from '@/api/modules/auth';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const globalStore = GlobalStore();
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
@@ -331,6 +336,9 @@ const appRef = ref();
|
|||||||
|
|
||||||
const isSafety = ref();
|
const isSafety = ref();
|
||||||
|
|
||||||
|
const welcomeOpen = ref();
|
||||||
|
const shadowContainer = ref();
|
||||||
|
|
||||||
const chartOption = ref('network');
|
const chartOption = ref('network');
|
||||||
let timer: NodeJS.Timer | null = null;
|
let timer: NodeJS.Timer | null = null;
|
||||||
let isInit = ref<boolean>(true);
|
let isInit = ref<boolean>(true);
|
||||||
@@ -692,6 +700,21 @@ const fetchData = () => {
|
|||||||
onLoadSimpleNode();
|
onLoadSimpleNode();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadWelcome = async () => {
|
||||||
|
await getWelcomePage().then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
welcomeOpen.value = true;
|
||||||
|
nextTick(() => {
|
||||||
|
const shadowRoot = shadowContainer.value.attachShadow({ mode: 'open' });
|
||||||
|
shadowRoot.innerHTML = res.data;
|
||||||
|
});
|
||||||
|
localStorage.setItem('welcomeShow', 'false');
|
||||||
|
} else {
|
||||||
|
localStorage.setItem('welcomeShow', 'false');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
onBeforeRouteUpdate((to, from, next) => {
|
onBeforeRouteUpdate((to, from, next) => {
|
||||||
if (to.name === 'home') {
|
if (to.name === 'home') {
|
||||||
clearTimer();
|
clearTimer();
|
||||||
@@ -707,6 +730,9 @@ const clearTimer = () => {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchData();
|
fetchData();
|
||||||
|
if (localStorage.getItem('welcomeShow') !== 'false') {
|
||||||
|
loadWelcome();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane :label="$t('commons.table.port')">
|
||||||
|
<PortConfig :exposedPorts="runtime.exposedPorts" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('runtime.environment')">
|
||||||
|
<Environment :environments="runtime.environments" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('container.mount')">
|
||||||
|
<Volumes :volumes="runtime.volumes" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('runtime.extraHosts')">
|
||||||
|
<ExtraHosts :extraHosts="runtime.extraHosts" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import PortConfig from '@/views/website/runtime/components/port/index.vue';
|
||||||
|
import Environment from '@/views/website/runtime/components/environment/index.vue';
|
||||||
|
import Volumes from '@/views/website/runtime/components/volume/index.vue';
|
||||||
|
import ExtraHosts from '@/views/website/runtime/components/extra_hosts/index.vue';
|
||||||
|
import { useVModel } from '@vueuse/core';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
|
interface RuntimeConfigFields {
|
||||||
|
exposedPorts: any[];
|
||||||
|
environments: any[];
|
||||||
|
volumes: any[];
|
||||||
|
extraHosts: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Object as PropType<RuntimeConfigFields>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:modelValue': [value: RuntimeConfigFields];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const runtime = useVModel(props, 'modelValue', emit);
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user