mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
fix(llm): derive aiproxy upstream model key from local_path sku (#25269)
This commit is contained in:
@@ -270,6 +270,11 @@ func collectUpstreamModelKeys(ctx context.Context, userCred mcclient.TokenCreden
|
||||
seen[key] = struct{}{}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
if key := UpstreamModelKeyFromLocalPathSku(llm, sku); key != "" {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "no mounted models on llm instance")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
@@ -88,6 +89,51 @@ func SkuHasLocalHostPathModel(sku *SLLMSku) bool {
|
||||
return hostPathsHasContainerMount(*sku.HostPaths, 0)
|
||||
}
|
||||
|
||||
func effectiveLLMPreferredModel(llm *SLLM, sku *SLLMSku) string {
|
||||
if llm != nil && llm.LLMSpec != nil {
|
||||
if llm.LLMSpec.Vllm != nil {
|
||||
if p := strings.TrimSpace(llm.LLMSpec.Vllm.PreferredModel); p != "" {
|
||||
return p
|
||||
}
|
||||
}
|
||||
if llm.LLMSpec.SGLang != nil {
|
||||
if p := strings.TrimSpace(llm.LLMSpec.SGLang.PreferredModel); p != "" {
|
||||
return p
|
||||
}
|
||||
}
|
||||
}
|
||||
if sku != nil && sku.LLMSpec != nil {
|
||||
if sku.LLMSpec.Vllm != nil {
|
||||
if p := strings.TrimSpace(sku.LLMSpec.Vllm.PreferredModel); p != "" {
|
||||
return p
|
||||
}
|
||||
}
|
||||
if sku.LLMSpec.SGLang != nil {
|
||||
if p := strings.TrimSpace(sku.LLMSpec.SGLang.PreferredModel); p != "" {
|
||||
return p
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// UpstreamModelKeyFromLocalPathSku returns the served model name vLLM/SGLang expose
|
||||
// for a local_path SKU (basename of the selected container model mount path).
|
||||
func UpstreamModelKeyFromLocalPathSku(llm *SLLM, sku *SLLMSku) string {
|
||||
if !SkuHasLocalHostPathModel(sku) {
|
||||
return ""
|
||||
}
|
||||
preferred := effectiveLLMPreferredModel(llm, sku)
|
||||
modelPath := PickContainerModelMountPath(CollectContainerModelMountPaths(llm, sku), preferred)
|
||||
if modelPath != "" {
|
||||
return path.Base(modelPath)
|
||||
}
|
||||
if lp := strings.TrimSpace(sku.LocalPath); lp != "" {
|
||||
return path.Base(lp)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ValidateLocalPathHamiDevicesRequireMemoryMb requires every HAMi device to set
|
||||
// memory_mb for local_path SKUs (no InstantModel VRAM estimate available).
|
||||
// Devices are normalized first so empty SharingMode (default HAMi) is treated
|
||||
|
||||
@@ -119,6 +119,46 @@ func TestSkuHasLocalHostPathModel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpstreamModelKeyFromLocalPathSku(t *testing.T) {
|
||||
hostPaths := llm.HostPaths{
|
||||
{
|
||||
Type: "directory",
|
||||
Path: "/data/models/Qwen3-8B",
|
||||
Containers: llm.ContainerHostPathRelations{
|
||||
"0": {MountPath: "/data/models/huggingface/Qwen3-8B"},
|
||||
},
|
||||
},
|
||||
}
|
||||
sku := &SLLMSku{
|
||||
LLMType: string(llm.LLM_CONTAINER_VLLM),
|
||||
Source: llm.LLM_MODEL_SOURCE_LOCAL_PATH,
|
||||
LocalPath: "/data/models/Qwen3-8B",
|
||||
}
|
||||
sku.HostPaths = &hostPaths
|
||||
|
||||
got := UpstreamModelKeyFromLocalPathSku(nil, sku)
|
||||
if got != "Qwen3-8B" {
|
||||
t.Fatalf("expected upstream model key Qwen3-8B, got %q", got)
|
||||
}
|
||||
|
||||
skuWithPreferred := &SLLMSku{
|
||||
LLMType: string(llm.LLM_CONTAINER_VLLM),
|
||||
Source: llm.LLM_MODEL_SOURCE_LOCAL_PATH,
|
||||
LocalPath: "/data/models/Qwen3-8B",
|
||||
LLMSpec: &llm.LLMSpec{Vllm: &llm.LLMSpecVllm{PreferredModel: "Qwen3-8B"}},
|
||||
}
|
||||
skuWithPreferred.HostPaths = &hostPaths
|
||||
got = UpstreamModelKeyFromLocalPathSku(nil, skuWithPreferred)
|
||||
if got != "Qwen3-8B" {
|
||||
t.Fatalf("expected upstream model key with preferred model, got %q", got)
|
||||
}
|
||||
|
||||
nonLocal := &SLLMSku{LLMType: string(llm.LLM_CONTAINER_VLLM)}
|
||||
if UpstreamModelKeyFromLocalPathSku(nil, nonLocal) != "" {
|
||||
t.Fatal("expected empty key for non local_path sku")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLocalPathHamiDevicesRequireMemoryMb(t *testing.T) {
|
||||
t.Run("hami without memory_mb fails", func(t *testing.T) {
|
||||
devs := llm.Devices{{Model: "A100", SharingMode: "HAMI"}}
|
||||
|
||||
Reference in New Issue
Block a user