mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
* feat: add preinstall for quick-models * fix: drop error when duplicate blobs
This commit is contained in:
+6
-6
@@ -119,9 +119,9 @@ type LLMSkuDetails struct {
|
||||
Template string
|
||||
}
|
||||
|
||||
// type MountedAppResourceDetails struct {
|
||||
// MountedApps []string `json:"mounted_apps"`
|
||||
// }
|
||||
type MountedAppResourceDetails struct {
|
||||
MountedModels []string `json:"mounted_models"`
|
||||
}
|
||||
|
||||
type LLMSKuBaseCreateInput struct {
|
||||
apis.SharableVirtualResourceCreateInput
|
||||
@@ -142,7 +142,6 @@ type LLMSKuBaseCreateInput struct {
|
||||
|
||||
type LLMSkuBaseUpdateInput struct {
|
||||
apis.SharableVirtualResourceBaseUpdateInput
|
||||
// MountedAppResourceUpdateInput
|
||||
|
||||
Cpu *int `json:"cpu"`
|
||||
Memory *int `json:"memory"`
|
||||
@@ -165,7 +164,7 @@ type LLMSkuBaseUpdateInput struct {
|
||||
|
||||
type LLMSkuListInput struct {
|
||||
apis.SharableVirtualResourceListInput
|
||||
// MountedAppResourceListInput
|
||||
MountedModelResourceListInput
|
||||
|
||||
LLMType string `json:"llm_type"`
|
||||
}
|
||||
@@ -180,6 +179,7 @@ type LLMSkuCreateInput struct {
|
||||
|
||||
type LLMSkuUpdateInput struct {
|
||||
LLMSkuBaseUpdateInput
|
||||
MountedModelResourceUpdateInput
|
||||
|
||||
LLMImageId string `json:"llm_image_id"`
|
||||
LLMModelName string `json:"llm_model_name"`
|
||||
@@ -195,7 +195,7 @@ type LLMSkuUpdateInput struct {
|
||||
|
||||
type DifySkulListInput struct {
|
||||
apis.SharableVirtualResourceListInput
|
||||
// MountedAppResourceListInput
|
||||
MountedModelResourceListInput
|
||||
}
|
||||
|
||||
type DifySkuCreateInput struct {
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
commonapi "yunion.io/x/onecloud/pkg/apis"
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
api "yunion.io/x/onecloud/pkg/apis/llm"
|
||||
@@ -37,7 +36,7 @@ func (o *ollama) GetType() api.LLMContainerType {
|
||||
|
||||
func (o *ollama) GetContainerSpec(ctx context.Context, llm *models.SLLM, image *models.SLLMImage, sku *models.SLLMSku, props []string, devices []computeapi.SIsolatedDevice, diskId string) *computeapi.PodContainerCreateInput {
|
||||
spec := computeapi.ContainerSpec{
|
||||
ContainerSpec: apis.ContainerSpec{
|
||||
ContainerSpec: commonapi.ContainerSpec{
|
||||
Image: image.ToContainerImage(),
|
||||
ImageCredentialId: image.CredentialId,
|
||||
EnableLxcfs: true,
|
||||
@@ -49,7 +48,7 @@ func (o *ollama) GetContainerSpec(ctx context.Context, llm *models.SLLM, image *
|
||||
for i := range *sku.Devices {
|
||||
index := i
|
||||
spec.Devices = append(spec.Devices, &computeapi.ContainerDevice{
|
||||
Type: apis.CONTAINER_DEVICE_TYPE_ISOLATED_DEVICE,
|
||||
Type: commonapi.CONTAINER_DEVICE_TYPE_ISOLATED_DEVICE,
|
||||
IsolatedDevice: &computeapi.ContainerIsolatedDevice{
|
||||
Index: &index,
|
||||
},
|
||||
@@ -58,7 +57,7 @@ func (o *ollama) GetContainerSpec(ctx context.Context, llm *models.SLLM, image *
|
||||
} else if len(devices) > 0 {
|
||||
for i := range devices {
|
||||
spec.Devices = append(spec.Devices, &computeapi.ContainerDevice{
|
||||
Type: apis.CONTAINER_DEVICE_TYPE_ISOLATED_DEVICE,
|
||||
Type: commonapi.CONTAINER_DEVICE_TYPE_ISOLATED_DEVICE,
|
||||
IsolatedDevice: &computeapi.ContainerIsolatedDevice{
|
||||
Id: devices[i].Id,
|
||||
},
|
||||
@@ -87,29 +86,28 @@ func (o *ollama) GetContainerSpec(ctx context.Context, llm *models.SLLM, image *
|
||||
// }
|
||||
|
||||
// process volume mounts
|
||||
vols := make([]*apis.ContainerVolumeMount, 0)
|
||||
// appVolIndex := 2
|
||||
// postOverlays, err := d.GetMountedAppsPostOverlay()
|
||||
// if err != nil {
|
||||
// log.Errorf("GetMountedAppsPostOverlay failed %s", err)
|
||||
// }
|
||||
// vols = append(spec.VolumeMounts, GetDiskVolumeMounts(sku.Volumes, appVolIndex, postOverlays)...)
|
||||
postOverlays, err := llm.GetMountedModelsPostOverlay()
|
||||
if err != nil {
|
||||
log.Errorf("GetMountedModelsPostOverlay failed %s", err)
|
||||
}
|
||||
vols := spec.VolumeMounts
|
||||
|
||||
// udevPath := filepath.Join(GetTmpSocketsHostPath(d.GetName()), "udev")
|
||||
diskIndex := 0
|
||||
ctrVols := []*apis.ContainerVolumeMount{
|
||||
ctrVols := []*commonapi.ContainerVolumeMount{
|
||||
{
|
||||
Disk: &apis.ContainerVolumeMountDisk{
|
||||
Disk: &commonapi.ContainerVolumeMountDisk{
|
||||
SubDirectory: api.LLM_OLLAMA,
|
||||
Overlay: &apis.ContainerVolumeMountDiskOverlay{
|
||||
Overlay: &commonapi.ContainerVolumeMountDiskOverlay{
|
||||
LowerDir: []string{api.LLM_OLLAMA_HOST_PATH},
|
||||
},
|
||||
Index: &diskIndex,
|
||||
PostOverlay: postOverlays,
|
||||
Index: &diskIndex,
|
||||
},
|
||||
Type: apis.CONTAINER_VOLUME_MOUNT_TYPE_DISK,
|
||||
Type: commonapi.CONTAINER_VOLUME_MOUNT_TYPE_DISK,
|
||||
MountPath: api.LLM_OLLAMA_BASE_PATH,
|
||||
ReadOnly: false,
|
||||
Propagation: apis.MOUNTPROPAGATION_PROPAGATION_HOST_TO_CONTAINER,
|
||||
Propagation: commonapi.MOUNTPROPAGATION_PROPAGATION_HOST_TO_CONTAINER,
|
||||
},
|
||||
}
|
||||
vols = append(vols, ctrVols...)
|
||||
@@ -360,6 +358,18 @@ func (o *ollama) ValidateMounts(mounts []string, mdlName string, mdlTag string)
|
||||
return mounts, nil
|
||||
}
|
||||
|
||||
func (o *ollama) CheckDuplicateMounts(errStr string, dupIndex int) string {
|
||||
// Find the first model path before "duplicated container target dirs"
|
||||
firstPath := extractModelPath(errStr[:dupIndex], api.LLM_OLLAMA_MANIFESTS_BASE_PATH, true)
|
||||
firstModel := parseModelName(firstPath)
|
||||
|
||||
// Find the second model path after "duplicated container target dirs"
|
||||
secondPath := extractModelPath(errStr[dupIndex:], api.LLM_OLLAMA_MANIFESTS_BASE_PATH, false)
|
||||
secondModel := parseModelName(secondPath)
|
||||
|
||||
return fmt.Sprintf("Model %s and %s have duplicated container target dirs", firstModel, secondModel)
|
||||
}
|
||||
|
||||
// func download(ctx context.Context, userCred mcclient.TokenCredential, containerId string, taskId string, webUrl string, path string) error {
|
||||
// input := &computeapi.ContainerDownloadFileInput{
|
||||
// WebUrl: webUrl,
|
||||
@@ -451,3 +461,53 @@ func getManifests(ctx context.Context, containerId string, modelName string, mod
|
||||
|
||||
return manifests, nil
|
||||
}
|
||||
|
||||
func extractModelPath(str, startMarker string, findLast bool) string {
|
||||
var idx int
|
||||
if findLast {
|
||||
idx = strings.LastIndex(str, startMarker)
|
||||
} else {
|
||||
idx = strings.Index(str, startMarker)
|
||||
}
|
||||
|
||||
if idx == -1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
pathStart := idx
|
||||
pathEnd := -1
|
||||
for i := pathStart; i < len(str); i++ {
|
||||
if str[i] == '\\' && i+4 < len(str) && str[i+1] == '\\' && str[i+2] == '\\' && str[i+3] == '\\' && str[i+4] == '"' { // for \\\\\"
|
||||
pathEnd = i
|
||||
break
|
||||
}
|
||||
if str[i] == '"' || str[i] == ',' || str[i] == ':' || str[i] == '}' {
|
||||
pathEnd = i
|
||||
break
|
||||
}
|
||||
}
|
||||
var extracted string
|
||||
if pathEnd != -1 {
|
||||
extracted = str[pathStart:pathEnd]
|
||||
} else {
|
||||
extracted = str[pathStart:]
|
||||
}
|
||||
|
||||
return extracted
|
||||
}
|
||||
|
||||
func parseModelName(path string) string {
|
||||
if !strings.HasPrefix(path, api.LLM_OLLAMA_MANIFESTS_BASE_PATH) {
|
||||
return ""
|
||||
}
|
||||
model := strings.TrimPrefix(path, api.LLM_OLLAMA_MANIFESTS_BASE_PATH)
|
||||
model = strings.TrimPrefix(model, "/")
|
||||
lastSlash := strings.LastIndex(model, "/")
|
||||
if lastSlash != -1 {
|
||||
name := model[:lastSlash]
|
||||
tag := model[lastSlash+1:]
|
||||
tag = strings.TrimRight(tag, `\`)
|
||||
return name + ":" + tag
|
||||
}
|
||||
return strings.TrimRight(model, `\`)
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
api "yunion.io/x/onecloud/pkg/apis/llm"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -252,6 +254,35 @@ func (llm *SLLMBase) GetVolume() (*SVolume, error) {
|
||||
return volume, nil
|
||||
}
|
||||
|
||||
func GetDiskVolumeMounts(vols *api.Volumes, containerIndex int, postOverlays []*apis.ContainerVolumeMountDiskPostOverlay) []*apis.ContainerVolumeMount {
|
||||
if vols == nil {
|
||||
return nil
|
||||
}
|
||||
mounts := make([]*apis.ContainerVolumeMount, 0)
|
||||
for idx, vol := range *vols {
|
||||
volRelation := vol.GetVolumeByContainer(containerIndex)
|
||||
if volRelation == nil {
|
||||
continue
|
||||
}
|
||||
mounts = append(mounts, &apis.ContainerVolumeMount{
|
||||
UniqueName: fmt.Sprintf("volume-%d-%d-%s", idx, containerIndex, volRelation.MountPath),
|
||||
Type: apis.CONTAINER_VOLUME_MOUNT_TYPE_DISK,
|
||||
MountPath: volRelation.MountPath,
|
||||
Propagation: apis.MOUNTPROPAGATION_PROPAGATION_HOST_TO_CONTAINER,
|
||||
Disk: &apis.ContainerVolumeMountDisk{
|
||||
Index: &idx,
|
||||
SubDirectory: volRelation.SubDirectory,
|
||||
Overlay: volRelation.Overlay,
|
||||
PostOverlay: postOverlays,
|
||||
},
|
||||
FsUser: volRelation.FsUser,
|
||||
FsGroup: volRelation.FsGroup,
|
||||
})
|
||||
}
|
||||
|
||||
return mounts
|
||||
}
|
||||
|
||||
// 取消自动删除
|
||||
func (llm *SLLMBase) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return nil
|
||||
|
||||
@@ -75,6 +75,7 @@ type ILLMContainerInstantApp interface {
|
||||
GetSaveDirectories(sApp *SInstantModel) (string, []string, error)
|
||||
|
||||
ValidateMounts(mounts []string, mdlName string, mdlTag string) ([]string, error)
|
||||
CheckDuplicateMounts(errStr string, dupIndex int) string
|
||||
GetInstantModelIdByPostOverlay(postOverlay *commonapi.ContainerVolumeMountDiskPostOverlay, mdlNameToId map[string]string) string
|
||||
GetDirPostOverlay(dir llm.LLMMountDirInfo) *commonapi.ContainerVolumeMountDiskPostOverlay
|
||||
|
||||
|
||||
@@ -72,6 +72,20 @@ func (man *SLLMInstantModelManager) fetchLLMInstantModel(llmId string, mdlId str
|
||||
return &llmInstantModel, nil
|
||||
}
|
||||
|
||||
func (man *SLLMInstantModelManager) getDeletedModelIds(llmId string) ([]string, error) {
|
||||
q := man.RawQuery("model_id").Equals("llm_id", llmId).IsTrue("deleted").Distinct()
|
||||
llmInstantModel := make([]SLLMInstantModel, 0)
|
||||
err := db.FetchModelObjects(man, q, &llmInstantModel)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Query")
|
||||
}
|
||||
modelIds := make([]string, len(llmInstantModel))
|
||||
for i := range llmInstantModel {
|
||||
modelIds[i] = llmInstantModel[i].ModelId
|
||||
}
|
||||
return modelIds, nil
|
||||
}
|
||||
|
||||
func (man *SLLMInstantModelManager) updateInstantModel(ctx context.Context, llmId string, mdlId string, mdlName string, tag string, probed, mounted *bool) (*SLLMInstantModel, error) {
|
||||
mdl, err := man.fetchLLMInstantModel(llmId, mdlId)
|
||||
if err != nil && errors.Cause(err) != errors.ErrNotFound {
|
||||
|
||||
@@ -3,7 +3,9 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -586,6 +588,116 @@ func (llm *SLLM) UpdateVolumeMountedModelFullNames(mdlFullNames []string) error
|
||||
return volume.UpdateMountedModelFullNames(mdlFullNames)
|
||||
}
|
||||
|
||||
type mdlFullNameInfo struct {
|
||||
ModelId string
|
||||
ModelFullName string
|
||||
IsMounted bool
|
||||
}
|
||||
|
||||
func (llm *SLLM) UpdateMountedModelFullNames(ctx context.Context, mdlinfos []string, isReset bool, imageId string, skuId string) error {
|
||||
mdlFullNameInfos := make(map[string]*mdlFullNameInfo)
|
||||
for i := range mdlinfos {
|
||||
parts := strings.Split(mdlinfos[i], "@")
|
||||
mdlFullNameInfos[parts[0]] = &mdlFullNameInfo{
|
||||
ModelId: parts[0],
|
||||
ModelFullName: parts[1],
|
||||
IsMounted: false,
|
||||
}
|
||||
}
|
||||
|
||||
preinstallModel := true
|
||||
|
||||
if preinstallModel {
|
||||
sku, err := llm.GetLLMSku(skuId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetLLMSku")
|
||||
}
|
||||
var deletedModelIds []string
|
||||
if !isReset {
|
||||
deletedModelIds, err = GetLLMInstantModelManager().getDeletedModelIds(llm.Id)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getDeletedModelIds")
|
||||
}
|
||||
}
|
||||
for i := range sku.MountedModels {
|
||||
parts := strings.Split(sku.MountedModels[i], "@")
|
||||
if !isReset && slices.Contains(deletedModelIds, parts[0]) {
|
||||
// if not reset, and the package is deleted, skip it
|
||||
continue
|
||||
}
|
||||
if _, ok := mdlFullNameInfos[parts[0]]; !ok {
|
||||
mdlFullNameInfos[parts[0]] = &mdlFullNameInfo{
|
||||
ModelId: parts[0],
|
||||
ModelFullName: parts[1],
|
||||
IsMounted: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolTrue := true
|
||||
boolFalse := false
|
||||
mountedModels, err := llm.FetchModels(nil, &boolTrue, nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchApps")
|
||||
}
|
||||
for i := range mountedModels {
|
||||
find := false
|
||||
if _, ok := mdlFullNameInfos[mountedModels[i].ModelId]; ok {
|
||||
find = true
|
||||
mdlFullNameInfos[mountedModels[i].ModelId].IsMounted = true
|
||||
}
|
||||
if isReset && !find {
|
||||
// remove instant model not in mdlInfos
|
||||
mountedModel := mountedModels[i]
|
||||
log.Debugf("UpdateMountedModelFullNames remove model %s", mountedModel.ModelId)
|
||||
_, err := GetLLMInstantModelManager().updateInstantModel(ctx, llm.Id, mountedModel.ModelId, "", "", &boolFalse, &boolFalse)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "remove instant model")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
installModelFullNames := make([]string, 0)
|
||||
for _, mdlFullNameInfo := range mdlFullNameInfos {
|
||||
installModelFullNames = append(installModelFullNames, fmt.Sprintf("%s-%s", mdlFullNameInfo.ModelFullName, mdlFullNameInfo.ModelId))
|
||||
if !mdlFullNameInfo.IsMounted {
|
||||
modelName, modelTag, _ := llm.GetLargeLanguageModelName(mdlFullNameInfo.ModelFullName)
|
||||
_, err := GetLLMInstantModelManager().updateInstantModel(ctx, llm.Id, mdlFullNameInfo.ModelId, modelName, modelTag, &boolFalse, &boolTrue)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "install model")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volume, _ := llm.GetVolume()
|
||||
if volume != nil {
|
||||
err := llm.UpdateVolumeMountedModelFullNames(installModelFullNames)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "UpdateVolumeMountedModelFullNames")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (llm *SLLM) GetMountedModelsPostOverlay() ([]*commonapi.ContainerVolumeMountDiskPostOverlay, error) {
|
||||
boolTrue := true
|
||||
mdls, err := llm.FetchModels(nil, &boolTrue, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetchApps")
|
||||
}
|
||||
if len(mdls) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
drv := llm.GetLLMContainerDriver()
|
||||
overlays, err := models2overlays(drv, mdls, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "models2overlays")
|
||||
}
|
||||
return overlays, nil
|
||||
}
|
||||
|
||||
func (llm *SLLM) getMountingModelsPostOverlay(ctx context.Context, input apis.LLMSyncModelTaskInput, existingMdls []SLLMInstantModel) ([]SLLMInstantModel, []*commonapi.ContainerVolumeMountDiskPostOverlay, error) {
|
||||
var models []SLLMInstantModel
|
||||
for i := range input.Models {
|
||||
|
||||
@@ -24,6 +24,14 @@ func GetLLMPodCreateInput(
|
||||
return nil, errors.Wrap(err, "GetLLMBasePodCreateInput: ")
|
||||
}
|
||||
|
||||
// generate post overlay info
|
||||
{
|
||||
err = llm.UpdateMountedModelFullNames(ctx, nil, true, input.LLMImageId, input.LLMSkuId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "UpdateMountedModelFullNames")
|
||||
}
|
||||
}
|
||||
|
||||
lcd := llm.GetLLMContainerDriver()
|
||||
llmContainer := lcd.GetContainerSpec(ctx, llm, llmImage, sku, nil, nil, "")
|
||||
|
||||
|
||||
@@ -41,11 +41,12 @@ func GetLLMSkuManager() *SLLMSkuManager {
|
||||
|
||||
type SLLMSkuManager struct {
|
||||
SLLMSkuBaseManager
|
||||
SMountedModelsResourceManager
|
||||
}
|
||||
|
||||
type SLLMSku struct {
|
||||
SLLMSkuBase
|
||||
// SMountedAppsResource
|
||||
SMountedModelsResource
|
||||
|
||||
LLMImageId string `width:"128" charset:"ascii" nullable:"false" list:"user" create:"required"`
|
||||
LLMType string `width:"128" charset:"ascii" nullable:"false" list:"user" create:"required"`
|
||||
@@ -66,10 +67,10 @@ func (man *SLLMSkuManager) ListItemFilter(
|
||||
if len(input.LLMType) > 0 {
|
||||
q = q.Equals("llm_type", input.LLMType)
|
||||
}
|
||||
// q, err = man.SMountedAppsResourceManager.ListItemFilter(ctx, q, userCred, input.MountedAppResourceListInput)
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrap(err, "SMountedAppsResourceManager")
|
||||
// }
|
||||
q, err = man.SMountedModelsResourceManager.ListItemFilter(ctx, q, userCred, input.MountedModelResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SMountedAppsResourceManager")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,11 @@ func (task *LLMCreateTask) OnLLMRefreshStatusComplete(ctx context.Context, llm *
|
||||
return
|
||||
}
|
||||
|
||||
mountedModels, err := llm.FetchMountedModelFullName()
|
||||
if err != nil {
|
||||
task.taskFailed(ctx, llm, errors.Wrap(err, "FetchMountedModelFullName"))
|
||||
}
|
||||
|
||||
// 创建磁盘
|
||||
for _, disk := range server.DisksInfo {
|
||||
volume := models.SVolume{}
|
||||
@@ -106,7 +111,7 @@ func (task *LLMCreateTask) OnLLMRefreshStatusComplete(ctx context.Context, llm *
|
||||
// if len(input.TemplateId) > 0 {
|
||||
volume.TemplateId = disk.ImageId
|
||||
// }
|
||||
// volume.MountedApps = mountedApps
|
||||
volume.MountedModels = mountedModels
|
||||
|
||||
err := models.GetVolumeManager().TableSpec().Insert(ctx, &volume)
|
||||
if err != nil {
|
||||
@@ -159,22 +164,4 @@ func (task *LLMCreateTask) OnLLMRefreshStatusComplete(ctx context.Context, llm *
|
||||
}
|
||||
|
||||
task.taskComplete(ctx, llm, server.Status)
|
||||
// // 调用子任务在容器中拉取模型
|
||||
// params := jsonutils.NewDict()
|
||||
// params.Set("status", jsonutils.NewString(server.Status))
|
||||
// task.SetStage("OnLLMPullModel", params)
|
||||
|
||||
// if err := llm.StartPullModelTask(ctx, task.GetUserCred(), nil, task.GetId()); err != nil {
|
||||
// task.taskFailed(ctx, llm, errors.Wrap(err, "StartPullModelTask"))
|
||||
// return
|
||||
// }
|
||||
}
|
||||
|
||||
// func (task *LLMCreateTask) OnLLMPullModelFailed(ctx context.Context, llm *models.SLLM, err jsonutils.JSONObject) {
|
||||
// task.taskFailed(ctx, llm, errors.Error(err.String()))
|
||||
// }
|
||||
|
||||
// func (task *LLMCreateTask) OnLLMPullModel(ctx context.Context, llm *models.SLLM, body jsonutils.JSONObject) {
|
||||
// status, _ := task.GetParams().GetString("status")
|
||||
// task.taskComplete(ctx, llm, status)
|
||||
// }
|
||||
|
||||
@@ -2,6 +2,7 @@ package llm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -118,7 +119,7 @@ func (task *LLMInstantModelsSyncTask) OnModelsUnmountComplete(ctx context.Contex
|
||||
return llm.TryContainerMountPaths(ctx, task.UserCred, s, overlays, 7200)
|
||||
})
|
||||
if err != nil {
|
||||
task.OnModelsUnmountCompleteFailed(ctx, llm, jsonutils.NewString(errors.Wrap(err, "TryContainerMountPaths").Error()))
|
||||
task.OnModelsMountCompleteFailed(ctx, llm, jsonutils.NewString(errors.Wrap(err, "TryContainerMountPaths").Error()))
|
||||
}
|
||||
} else {
|
||||
task.OnModelsMountComplete(ctx, llm, nil)
|
||||
@@ -184,8 +185,17 @@ func (task *LLMInstantModelsSyncTask) OnModelsMountComplete(ctx context.Context,
|
||||
|
||||
func (task *LLMInstantModelsSyncTask) OnModelsMountCompleteFailed(ctx context.Context, obj db.IStandaloneModel, err jsonutils.JSONObject) {
|
||||
llm := obj.(*models.SLLM)
|
||||
task.taskFailed(ctx, llm, err.String())
|
||||
|
||||
// get duplicated error
|
||||
errStr := err.String()
|
||||
dupMarker := "duplicated container target dirs map"
|
||||
dupIndex := strings.Index(errStr, dupMarker)
|
||||
if dupIndex != -1 {
|
||||
drv := llm.GetLLMContainerDriver()
|
||||
errStr = drv.CheckDuplicateMounts(errStr, dupIndex)
|
||||
}
|
||||
|
||||
task.taskFailed(ctx, llm, errStr)
|
||||
// sync status to clear failed status of container
|
||||
llm.StartSyncStatusTask(ctx, task.UserCred, "")
|
||||
}
|
||||
|
||||
@@ -52,22 +52,6 @@ func (t *LLMStartTask) requestStart(ctx context.Context, llm *models.SLLM) {
|
||||
t.taskFailed(ctx, llm, err.Error())
|
||||
return
|
||||
}
|
||||
// worker.StartTaskRun(t, func() (jsonutils.JSONObject, error) {
|
||||
// _, err := llm.WaitServerStatus(ctx, t.GetUserCred(), []string{computeapi.VM_RUNNING}, 900)
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrap(err, "WaitServerStatus")
|
||||
// }
|
||||
// time.Sleep(time.Second)
|
||||
// _, err = d.WaitServerStatus(ctx, task.UserCred, []string{computeapi.VM_RUNNING}, 900)
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrap(err, "WaitServerStatus")
|
||||
// }
|
||||
// return nil, nil
|
||||
// })
|
||||
// if err := llm.RunModel(ctx, t.GetUserCred()); nil != err {
|
||||
// t.OnStartedFailed(ctx, llm, jsonutils.NewString(err.Error()))
|
||||
// return
|
||||
// }
|
||||
}
|
||||
|
||||
func (t *LLMStartTask) OnStartedFailed(ctx context.Context, llm *models.SLLM, err jsonutils.JSONObject) {
|
||||
|
||||
@@ -56,6 +56,8 @@ func (o *LLMSkuDeleteOptions) Params() (jsonutils.JSONObject, error) {
|
||||
type LLMSkuUpdateOptions struct {
|
||||
LLMSkuBaseUpdateOptions
|
||||
|
||||
MountedModels []string `help:"mounted models, <model_id>@<model_name>:<model_tag> e.g. 6f48b936a09f@qwen2:0.5b" json:"mounted_models"`
|
||||
|
||||
LlmImageId string
|
||||
LlmModelName string
|
||||
}
|
||||
@@ -70,5 +72,6 @@ func (o *LLMSkuUpdateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
obj.Unmarshal(dict)
|
||||
|
||||
o.LLMSkuBaseUpdateOptions.Params(dict)
|
||||
fetchMountedModels(o.MountedModels, dict)
|
||||
return dict, nil
|
||||
}
|
||||
|
||||
@@ -217,8 +217,8 @@ func fetchProperties(propStrs []string, dict *jsonutils.JSONDict) {
|
||||
}
|
||||
}
|
||||
|
||||
// func fetchMountedApps(apps []string, dict *jsonutils.JSONDict) {
|
||||
// if len(apps) > 0 {
|
||||
// dict.Set("mounted_apps", jsonutils.Marshal(apps))
|
||||
// }
|
||||
// }
|
||||
func fetchMountedModels(mdls []string, dict *jsonutils.JSONDict) {
|
||||
if len(mdls) > 0 {
|
||||
dict.Set("mounted_models", jsonutils.Marshal(mdls))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user