diff --git a/src/pages/llmodels/config/types.ts b/src/pages/llmodels/config/types.ts index ff345b1d..6579e193 100644 --- a/src/pages/llmodels/config/types.ts +++ b/src/pages/llmodels/config/types.ts @@ -18,6 +18,16 @@ export interface ListItem { enable_model_route?: boolean; replicas: number; s3Address: string; + lora_list: Array<{ + huggingface_filename: string; + local_path: string; + lora_name: string; + lora_repo_name: string; + model_file_id: string; + model_scope_file_path: string; + path: string; + source: string; + }>; name: string; description: string; id: number; diff --git a/src/pages/model-routes/config/types.ts b/src/pages/model-routes/config/types.ts index 83803b58..8266cfc5 100644 --- a/src/pages/model-routes/config/types.ts +++ b/src/pages/model-routes/config/types.ts @@ -8,6 +8,7 @@ export interface FormData { provider_model_name?: string; model_id?: number; provider_id?: number; + lora_module_name?: string; fallback_status_codes?: string[]; }; targets: { @@ -15,6 +16,7 @@ export interface FormData { weight?: number | null; model_id?: number; provider_id?: number; + lora_module_name?: string; fallback_status_codes?: string[]; }[]; } @@ -46,5 +48,6 @@ export interface RouteTarget { provider_id: number; provider_model_name: string; fallback_status_codes: string[]; + lora_module_name?: string; state: string; } diff --git a/src/pages/model-routes/forms/index.tsx b/src/pages/model-routes/forms/index.tsx index 94f0543c..23696f4c 100644 --- a/src/pages/model-routes/forms/index.tsx +++ b/src/pages/model-routes/forms/index.tsx @@ -94,7 +94,10 @@ const AccessForm: React.FC = forwardRef((props, ref) => { if (fallbackTarget) { const exsitinged = targetList.find((ep) => { if (fallbackTarget!.model_id) { - return ep.model_id === fallbackTarget!.model_id; + return ( + ep.model_id === fallbackTarget!.model_id && + ep.lora_module_name === fallbackTarget!.lora_module_name + ); } return ( ep.provider_id === fallbackTarget!.provider_id && @@ -104,7 +107,8 @@ const AccessForm: React.FC = forwardRef((props, ref) => { if (exsitinged) { targetList = targetList.map((ep) => { if ( - ep.model_id === fallbackTarget.model_id || + (ep.model_id === fallbackTarget.model_id && + ep.lora_module_name === fallbackTarget.lora_module_name) || ep.provider_model_name === fallbackTarget.provider_model_name ) { return { @@ -150,6 +154,7 @@ const AccessForm: React.FC = forwardRef((props, ref) => { model_id?: number; provider_id?: number; provider_model_name?: string; + lora_module_name?: string; }[] ) => { // init targets form list @@ -157,7 +162,12 @@ const AccessForm: React.FC = forwardRef((props, ref) => { targets?.map((ep) => ({ weight: ep.weight, value: ep.model_id - ? ['deployments', ep.model_id] + ? [ + 'deployments', + ep.lora_module_name + ? `${ep.model_id}_lora_${ep.lora_module_name}` + : ep.model_id + ] : [ep.provider_id, ep.provider_model_name] })) || [] ); @@ -180,7 +190,12 @@ const AccessForm: React.FC = forwardRef((props, ref) => { if (fallbackTarget) { targetsRef.current?.initFallbackValues({ value: fallbackTarget.model_id - ? ['deployments', fallbackTarget.model_id] + ? [ + 'deployments', + fallbackTarget.lora_module_name + ? `${fallbackTarget.model_id}_lora_${fallbackTarget.lora_module_name}` + : fallbackTarget.model_id + ] : [fallbackTarget.provider_id, fallbackTarget.provider_model_name] }); } diff --git a/src/pages/model-routes/forms/targets.tsx b/src/pages/model-routes/forms/targets.tsx index 80e5964a..03460836 100644 --- a/src/pages/model-routes/forms/targets.tsx +++ b/src/pages/model-routes/forms/targets.tsx @@ -25,6 +25,18 @@ const OptionWrapper = styled.span` display: flex; align-items: center; gap: 8px; + .lora-tag { + display: inline-flex; + align-items: center; + padding: 0 7px; + height: 18px; + font-size: 11px; + line-height: 18px; + border: 1px solid var(--ant-color-split); + border-radius: 12px; + color: var(--ant-color-text-tertiary); + background-color: transparent; + } `; const LabelWrapper = styled.div` @@ -214,6 +226,14 @@ const TargetsForm = forwardRef((props, ref) => { const { data } = option; if (!data.isParent) { + if (data.isLora) { + return ( + + {data.label} + LoRA + + ); + } return {data.label}; } diff --git a/src/pages/model-routes/hooks/use-target-source-models.tsx b/src/pages/model-routes/hooks/use-target-source-models.tsx index d7376d77..034cab7f 100644 --- a/src/pages/model-routes/hooks/use-target-source-models.tsx +++ b/src/pages/model-routes/hooks/use-target-source-models.tsx @@ -48,15 +48,37 @@ const useTargetSourceModels = () => { parent: false, isParent: true, children: _.uniqBy( - models.items?.map?.((model: ModelListItem) => ({ - label: model.name, - value: model.id, - data: { - model_id: model.id, - parentId: 'deployments' - }, - source: 'deployment' - })), + models.items?.flatMap?.((model: ModelListItem) => { + const items: any[] = [ + { + label: model.name, + value: model.id, + data: { + model_id: model.id, + parentId: 'deployments' + }, + source: 'deployment' + } + ]; + model.lora_list?.forEach?.((lora) => { + const loraName = lora.lora_name || lora.lora_repo_name; + if (!loraName) { + return; + } + items.push({ + label: loraName, + value: `${model.id}_lora_${loraName}`, + data: { + model_id: model.id, + parentId: 'deployments', + lora_module_name: loraName + }, + source: 'deployment', + isLora: true + }); + }); + return items; + }) || [], 'value' ) }