|
- /* ******************************************************************************
- * 2019 - present Contributed by Apulis Technology (Shenzhen) Co. LTD
- *
- * This program and the accompanying materials are made available under the
- * terms of the MIT License, which is available at
- * https://www.opensource.org/licenses/MIT
- *
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- * SPDX-License-Identifier: MIT
- ******************************************************************************/
- package services
-
- import (
- "github.com/apulis/app/ai-arts-backend/internal/configs"
- "github.com/apulis/app/ai-arts-backend/internal/dto"
- "github.com/apulis/app/ai-arts-backend/pkg/exports"
- "fmt"
- )
-
- type ModelDeviceDesc struct{
- ComputeType string `json:"type"`
- Series string `json:"series"`
- DeviceNum int `json:"deviceNum"`
- Cpu int `json:"cpu"`
- Memory int64 `json:"memory"`
- //[experimental] indicate how many nodes use this device config should be used !
- MaxNodes int `json:"maxNode"`
- MinNodes int `json:"minNode"`
- }
-
- type ModelVersionInfo struct{
- Devices []ModelDeviceDesc `json:"devices"`
- DistributedFramework string `json:"distributedFramework"`
- }
-
- func(d*ModelVersionInfo) MatchQuota (quota*AomQuotaDetail) (int,int,APIError){
- for _,v := range d.Devices{
- if v.CheckWithQuota(quota){
- minDevNum := v.DeviceNum
- if d.DistributedFramework != "" {
- maxNode := v.MaxNodes
- if maxNode <= 0 {
- maxNode = MAX_VCJOB_NODE
- }
- return minDevNum,maxNode,nil
- }else{
- return minDevNum,1,nil
- }
- }
- }
- return 0,0,exports.RaiseAPIError(exports.AIARTS_NOT_FOUND,"cannot found match device used by model !")
- }
-
- func(d*ModelDeviceDesc)CheckWithQuota(qutoa*AomQuotaDetail) bool{
- return qutoa.CpuNum >= d.Cpu && qutoa.Mem >= d.Memory &&
- qutoa.ComputeType == d.ComputeType && ( d.Series == "" || d.Series == qutoa.Series)
- }
-
- func getModelDeviceDesc(modelId uint64,modelVersionId uint64) (*ModelVersionInfo,APIError){
- if modelId == 0 || modelVersionId == 0{
- return nil, exports.ParameterError("invalid modelId or modelVersionId !!!")
- }
- url := fmt.Sprintf("%s/studioModelVersion/%d/%d", configs.GetAppConfig().Resources.ApWorkShop,modelId,modelVersionId)
-
- type Response struct {
- Info ModelVersionInfo `json:"modelVersion"`
- }
- var modelVersionDetail Response
- if err := AIStudioRequest(url, "GET", nil,nil, &modelVersionDetail); err != nil {
- return nil, err
- }
- for idx,_ := range modelVersionDetail.Info.Devices {
- modelVersionDetail.Info.Devices[idx].Memory <<= 30
- if modelVersionDetail.Info.Devices[idx].ComputeType == "cpu" {
- modelVersionDetail.Info.Devices[idx].ComputeType = ""
- modelVersionDetail.Info.Devices[idx].DeviceNum = 0
- }
- }
- return &modelVersionDetail.Info,nil
- }
-
- func getResourceQuotaList(bearToken string, Type string) ([]AomQuotaDetail, APIError) {
- if Type == "" {
- return nil, exports.ParameterError("invalid quota type str !!!")
- }
- url := fmt.Sprintf("%s/resource-quotas?type=%s", configs.GetAppConfig().Resources.Aom,Type)
- type Response struct {
- Items []AomQuotaDetail `json:"items"`
- }
- var quotaList Response
- if err := AIStudioRequest(url, "GET", map[string]string{
- "Authorization": bearToken,
- }, nil, "aList); err != nil {
- return nil, err
- }
- return quotaList.Items,nil
- }
-
- func GetModelResourceQutoas(bearToken string,Type string,modelId uint64,modelVersionId uint64) ([]AomQuotaDetail,APIError){
- var err APIError
- var quotaList []AomQuotaDetail
- var modelVersion *ModelVersionInfo
- quotaList,err = getResourceQuotaList(bearToken,Type)
- if err != nil {
- return nil,err
- }
- //@mark: get resource-quotas without model information !
- if modelId == 0 || modelVersionId == 0 {
- return quotaList,nil
- }
- modelVersion,err=getModelDeviceDesc(modelId,modelVersionId)
- if err != nil {
- return nil,err
- }
- result := []AomQuotaDetail{}
- for _,q := range quotaList {
- for _,d := range modelVersion.Devices{
- if d.CheckWithQuota(&q){
-
- result=append(result,q)
- break
- }
- }
- }
- return result,nil
- }
-
- func ValidateModelResourceQutoa(bearToken string,quota* AomQuotaDetail,modelId uint64,modelVersionId uint64) (int,int,APIError){
-
- modelVersion,err := getModelDeviceDesc(modelId,modelVersionId)
- if err != nil {
- return 0,0,err
- }
- return modelVersion.MatchQuota(quota)
- }
-
- func transferModelDetail(modelInfo*dto.GetModelVersionDetailResp) * ModelVersionInfo {
- info := &ModelVersionInfo{
- DistributedFramework: modelInfo.ModelVersion.DistributedFramework,
- }
- for _,v := range modelInfo.ModelVersion.Device {
- if v.Type == "cpu" {//@mark: computeType="" indicate cpu
- v.Type = ""
- v.DeviceNum = 0
- }
- info.Devices = append(info.Devices,ModelDeviceDesc{
- ComputeType: v.Type,
- Series: v.Series,
- DeviceNum: v.DeviceNum,
- Cpu: v.CPU,
- Memory: int64(v.Memory)<<30,
- })
- }
- return info
- }
-
- func ValidateModelResourceQutoa2(quota* AomQuotaDetail,modelInfo*dto.GetModelVersionDetailResp) (int,int,APIError){
- return transferModelDetail(modelInfo).MatchQuota(quota)
- }
|