V2 独立版愿景

模型管理

HeteroFlow 是本站的异构算力与大模型调度产品。模型管理。模型管理 模型管理是 HeteroFlow 中"从一份模型文件到一个可调用 API 服务"的最短路径。散落在各 GPU 节点磁盘上的大模型文件(HuggingFace 权重目录、GGUF 单文件、乃至节点上已在运行的推理容器)由 Agent 自动扫描上报,平台汇聚成发现列表;管理…

模型管理

模型管理是 HeteroFlow 中"从一份模型文件到一个可调用 API 服务"的最短路径。散落在各 GPU 节点磁盘上的大模型文件(HuggingFace 权重目录、GGUF 单文件、乃至节点上已在运行的推理容器)由 Agent 自动扫描上报,平台汇聚成发现列表;管理员点一次"添加",平台在同一个请求里完成模型注册、引擎选择、服务编排、端点创建、API Key 发放与路由注册——请求返回时,服务已经可以被 OpenAI SDK 直接调用。

本模块管理三类彼此衔接的资产:模型注册表(ModelInfo,模型元数据台账)、模型路由(ModelRoute,模型名到推理服务的流量映射,网关选路依据)与模型级路由策略(model=auto 智能路由下每模型名的参与开关、用途标签与权重)。手动注册只登记元数据;"扫描发现 + 一键收录"才会自动创建推理服务。引擎探测与 GPU 算力选引擎见《推理服务》篇;路由决策在网关的执行细节(负载均衡、灰度、会话粘性)见《推理网关》篇。

功能总览

能力一句话说明状态
模型注册 CRUD手动注册/更新/删除/按名查询,多租户按租户隔离,节点引用做可见性校验已实现
模型自动发现Agent ModelScanner 定时扫描宿主机模型目录,随心跳上报 DiscoveredModel,前端一键收录已实现
引擎可用性探测Agent 每 20 次心跳重探 Docker 镜像/pip 包并无条件回灌路由器,inference_engines 是选引擎的第一权威依据真机验证
GPU 感知一键建服务按节点引擎可用性 + GPU 算力从模板链 vllm→sglang→llamacpp 选引擎,P100 等旧卡自动落 llama.cpp真机验证
模型路由 ModelRoute创建服务自动注册(priority=0/weight=100),支持手动管理与优先级/权重决策已实现
模型级路由策略model=auto 下按模型名配置参与开关、用途(chat/completion/embedding)与质量/速度/成本权重已实现
模型与推理服务联动注册即可调用;同名模型多节点部署时复用服务组追加副本;模板链供故障恢复跨引擎重建真机验证
API Key 发放一键建服务自动生成 sk- 前缀 Key,明文仅展示一次,库中只存 sha256 哈希已实现

一、模型注册 CRUD

模型注册表是平台的模型元数据台账:每行记录一个"模型名 + 节点 + 路径"三元组。同一模型名可以有多行(部署在多个节点上),按名查询会返回全部同名条目。

ModelInfo 字段

字段类型说明
idstring模型唯一标识(UUID)
namestring模型名称(可重复,同名多节点部署)
versionstring版本号(可选)
node_idstring所在节点 ID
model_pathstring模型文件在节点上的绝对路径
node_name / node_ipstring节点名称与 IP(展示用,可选)
sourcestringauto(自动扫描收录)/ 其他(手动添加)
model_typestring模型架构类型,如 qwen2、llama、chatglm(可选)
size_bytesint模型文件大小(字节,可选)
tenant_idstring归属租户(创建时取自调用方上下文)
created_at / updated_atstring创建/更新时间

各操作的行为边界

操作行为联动语义
手动创建 POST /api/v1/models仅登记元数据,不自动建推理服务与一键收录(见第三节)的关键区别
按名查询 GET /api/v1/models/by-name?name=返回所有同名模型(跨节点)多节点部署感知的基础
详情 GET /api/v1/models/{modelID}路径参数可以是 UUID(精确)或模型名(按名,命中多个返回列表)—
更新 PUT /api/v1/models/{modelID}仅更新提供的字段,空字段保留原值node_id 变化时重新做节点可见性校验
删除 DELETE /api/v1/models/{modelID}删除前做多租户归属校验(不能删别的租户的模型)不级联:已建的推理服务、端点与路由不受影响,需分别删除

节点可见性校验:POST /api/v1/models、PUT(仅 node_id 真的变化时)与一键收录引用的节点必须对调用方可见——共享节点对所有人可见,私有节点只对属主租户可见,节点不存在同样 404(不泄露其他租户有哪些节点)。校验发生在模型落库之前,杜绝"模型行挂在别的租户私有节点上"的脏数据。多租户隔离:非平台管理员只能看到/操作本租户的模型,按名查询也只返回本租户的同名模型,跨租户按 ID 读取一律 404。

二、模型自动发现(Agent ModelScanner)

模型自动发现回答一个问题:每个节点磁盘上到底有哪些模型。Agent 内置模型扫描器(agent/pkg/modelscanner),不需要人工登记。

扫描目录配置

配置来源优先级说明
Agent 配置文件 model_scan_dirs最高多目录列表
环境变量 HETEROFLOW_MODEL_SCAN_DIRS中多目录用逗号分隔,如 /data/models,/shared/models
默认值兜底仅模型缓存目录 /data/heteroflow/model-cache

两个要点容易踩坑:

  • model_scan_dirs 是替换语义,不是追加:一旦配置,默认缓存目录与环境变量都不再生效。仍想扫缓存目录必须把它显式写进列表。
  • /data/models 无条件追加:无论上面怎么配置,这个目录始终会被扫描,无法关闭。

每个扫描目录下若存在 hub、models/hub、models 子目录会自动追加,并支持 HuggingFace hub 缓存布局(models--<org>--<name>/snapshots/<hash>/)。

识别的模型形态

形态format识别条件
HuggingFace 权重目录huggingface目录下有 config.json 或 tokenizer_config.json,且同目录存在权重文件(.safetensors / .bin / .pt)
GGUF 文件gguf目录或扫描根下的 .gguf 文件;分片文件(model-00001-of-00003.gguf)自动合并为一组
运行中的推理容器apiAgent 额外发现节点上已在运行的 vLLM/SGLang/llama.cpp 容器及其经 /v1/models 加载的模型,model_type 形如 served-by:<engine>

模型架构类型从 config.json 的 _model_type 或 model_type 字段推断(如 qwen2、llama、chatglm)。

扫描节奏与去重

类型触发范围
全量扫描Agent 启动时所有扫描目录
增量扫描每 12 次心跳(默认心跳 5 秒,约 1 分钟)对比目录 mtime,仅重扫有变化的目录

扫描状态持久化在 {cacheDir}/.scan-state.json(记录每个目录的 mtime),Agent 重启后不必重复全量扫描。扫描结果随心跳以 discovered_models 上报,Server 侧汇聚为发现缓存(DiscoveredModelsCache)。

发现列表的可见性

GET /api/v1/models/discovered 叠加三层过滤:

1. 节点可见性:非平台运营者只返回共享节点与本租户私有节点的扫描结果;查不到节点记录的条目一律不返回(fail-closed);平台运营者看全部。

2. 在线过滤:仅返回 online/busy 节点的结果,离线节点的模型不可见。

3. 收录标记:已在注册表中的条目标记 added: true,前端据此区分"已添加/未添加"。

三、一键部署推理全流程(autoCreateInferenceService)

一键收录是本模块的核心价值:POST /api/v1/models/discovered/add 一个请求,把选中的发现模型变成可调用的推理服务。

前置:引擎可用性探测

选引擎的依据是节点心跳上报的 inference_engines 列表,它的可信度来自 Agent 侧的持续探测:

  • Agent 每 20 次心跳(约 100 秒)重新探测一次本地 Docker 镜像与 pip 包,并无条件回灌执行器的引擎路由器——避免"控制面认为引擎可用、Agent 侧路由器还冻结在启动时快照"的静默降级。
  • 探测是 GPU 感知的:vLLM 的 Docker 镜像只在存在 CC ≥ 7.5 的 NVIDIA GPU 时才被认作可用,旧卡上 pip 安装的 vLLM 标记为 vllm-legacy。
  • 镜像判定是精确匹配:本地必须存在与模板完全同名同 tag 的引用才算可用,只有内网私仓前缀的同名副本判为不可用——任务派发用的是裸引用,Agent 不会自动复用前缀不同的本地副本,内网仓库分发需 docker tag 成裸引用一次。

引擎/镜像选择(GPU 感知模板链)

控制面按"节点心跳上报的引擎可用性 + GPU 算力"从默认模板链中顺序选择:

模板链(按序尝试):
  1. vllm      vllm/vllm-openai:latest          门槛:NVIDIA CC ≥ 7.0
  2. sglang    lmsysorg/sglang:latest           —
  3. llamacpp  heteroflow/inference-llamacpp:gpu  —(平台自建 P100 兼容镜像)

选定条件 = 引擎在节点可用列表中 且 满足算力门槛;
全部不匹配 → 在创建任何资源之前明确失败(不进恢复循环)。
  • P100(CC 6.0)等旧卡会被 vLLM 的算力门槛拦下,自动落到 llama.cpp 兜底——与"P100 与 vLLM latest 不兼容"的真机结论一致。非 NVIDIA 卡或未上报算力时不按 CC 拦截,引擎可用列表是第一权威。
  • 链首是 vLLM(2026-09-12 调整,此前 SGLang 在前):SGLang 官方镜像在 L20 + 驱动 580 环境缺完整 CUDA 工具链,flashinfer JIT 必然失败;vLLM 模板已在多节点真机反复验证。
  • 链里另有一条 trtllm 条目仅作文档化(客户自带已编译引擎,只能显式指定),所有自动选择路径都跳过它。

一次请求创建的四类资源

一键收录(POST /api/v1/models/discovered/add)
  ├─ ① 模型入库(source=auto)
  ├─ ② TaskGroup:名称=模型名,task_type=inference,
  │      模板链写入 inference_templates(供恢复循环跨引擎 fallback 重建)
  ├─ ③ Endpoint:<模型名>-api(端口 8000,主机端口自动避让冲突)
  │      + API Key:sk-{UUID}(库中仅存 sha256 哈希)
  ├─ ④ rank-0 Task:镜像/引擎取自所选模板,model_path 落库,
  │      钉扎到模型所在节点(requested_node_id),提交调度器分配 GPU
  └─ ⑤ ModelRoute:priority=0(最高),weight=100
         → 此后按模型名经 /v1/chat/completions 即可调用

调度器分配 GPU、Agent 拉起容器后,服务即可用 OpenAI 兼容方式调用(Base URL http://<server>:3333/v1)。

失败、并发与配额

场景行为
节点选不出可用引擎模型注册成功,服务不创建,inference.error 说明原因(选不出引擎在创建任何资源前明确失败,不留半成品)
租户非 active / GPU 或端点配额不足模型注册仍成功(HTTP 200),inference.error 非空,error_code 为 quota_exceeded / tenant_inactive;配额检查与建任务/建组共用同一套检查与豁免口径
端点重名(此前建过服务且旧组已 failed/stopped)error_code = endpoint_name_conflict(409 语义),需先删同名端点或换模型名;模型注册本身成功,整体 HTTP 仍为 200
并发双击/重试同一(租户, 模型名)的创建全程串行化(进程内互斥 + 跨实例数据库咨询锁),拿不到锁按失败处理,不会建出重复任务
建服务中途出错已创建的资源回滚删除(任务、任务组、端点),不留孤儿资源

多节点扩展

同名模型已在本租户有活跃 TaskGroup 时再次一键收录:复用该组,为新节点追加一个 Task(递增 rank),更新组的副本计数,并幂等补建缺失的 ModelRoute。复用判据是严格同租户归属——不同租户的同名模型各建各的组。

四、模型路由 ModelRoute

ModelRoute 是"对外模型名 → 推理服务"的流量映射,网关收到 /v1/chat/completions 请求后按模型名查路由决定转发目标。

自动注册

创建推理服务(含一键收录)时自动注册一条:model_name 优先取请求体的 model_name(对外调用标识),未传时回退取服务名称;engine 从镜像名推断;priority=0(最高)、weight=100、status=active,租户继承 TaskGroup。两条特殊规则:

  • 训练组不注册路由:task_type=training 的组被显式挡掉,否则训练组会带着 active 路由污染对话接口的选路。
  • 复用/唤醒既有组时幂等补建:按(租户, 模型名)判定是否已有指向该模型名的路由,没有就补一条。同一个服务组因此可能同时挂着多条不同名字、不同租户的路由——这是跨租户复用的正常结果。

手动管理

接口说明
GET /api/v1/model-routes列出路由
POST /api/v1/model-routes创建(非平台运营者:priority 不得为负、模型名与 default 租户已有路由同名返回 409、只能指向自己创建的任务组)
PUT /api/v1/model-routes/{id}更新权重/优先级(不改模型名时不判同名)
DELETE /api/v1/model-routes/{id}删除

路由决策

同一模型名的多条路由按 priority 升序分组(0 最高),同组内按 weight 加权分流,高优先级组全部不健康时整体降级到下一组:

模型 "llama-3" 的 3 条路由:
  Route A: priority=0, weight=80, engine=vllm      (生产)
  Route B: priority=0, weight=20, engine=vllm      (金丝雀)
  Route C: priority=1, weight=100, engine=llamacpp (降级备选)

正常流量:80% → A,20% → B
A、B 都不健康:100% → C

这是灰度发布(生产/金丝雀按权重切流)与故障降级(备选组兜底)的基础机制;组内副本间的负载均衡算法、会话粘性与健康摘除由网关执行,见《推理网关》篇。

五、模型级路由策略(model=auto 智能路由)

模型级路由策略作用于智能路由:调用方把请求体里的 model 写成 auto,由平台在调用方租户内自动挑一个模型承接。每个模型名一份策略行,按(tenant_id + model_name)存储。

三层配置与三种策略

智能路由默认关闭(opt-in),配置分三层:密钥级覆盖 > 全局默认 > 关闭(全局开关与默认策略在推理控制面板设置,密钥级覆盖在"我的 API Key"页配置)。开启后按三种策略打分选模型:

策略打分依据
quality模型的质量静态权重(0-100)
speed速度静态权重,叠加近 30 分钟平均延迟惩罚
cost成本静态权重(目前只是占位,平台未内置真实价格数据)

策略字段

字段取值作用
routing_enabledbool关闭 = 该模型永不被 auto 选中(含降级链候选);手动指定该模型名调用不受影响
purposechat / completion / embedding / 未标注auto 按请求接口挑同用途的模型
quality_weight / speed_weight / cost_weight整数 0-100,缺省 50三种策略的静态排序分

无策略行 = 默认全量参与(权重全 50、用途未标注)。

用途过滤矩阵

请求接口接受的用途说明
/v1/chat/completions仅 chat—
/v1/completionscompletion 或 chat补全模型优先,对话模型可兜底
/v1/embeddings仅 embedding—

已标注且不匹配的模型一律排除;已标注且匹配的优先;未标注的模型只在没有任何已标注且匹配的模型时回退使用(响应头 X-Routing-Purpose-Fallback: unlabeled 可见)。全部不匹配返回 503 no_auto_candidates_for_purpose。

存量模型全部是"用途未标注":系统不按模型名或架构名猜用途,需要管理员逐个标注后 auto 才按用途区分;不标注时选路行为与引入用途之前完全一致。手动指定模型名调用不受用途影响。

执行语义

auto 请求单次最多尝试 3 个候选模型,主选异常按序降级;实际承接模型通过响应头 X-Routed-Model 透出。候选模型按调用方租户收窄,同名路由内按 priority 升序稳定排序后分组——与手动指定路径的裁决口径一致。错误码:no_auto_candidates(503,无候选)、no_auto_candidates_for_purpose(503)、auto_routing_all_failed(502,候选全失败)。

六、模型与推理服务联动

  • 注册即可调用:一键收录的模型在服务创建完成那一刻起就可按模型名经 OpenAI 兼容接口调用(自动注册的 ModelRoute 已生效)。
  • 多节点部署感知:模型列表按名聚合展示各节点副本;再往新节点一键收录时自动并入同一服务组。
  • 故障恢复联动:模板链写入 TaskGroup 的 inference_templates,服务故障进入恢复循环时可跨引擎 fallback 重建(如 vLLM 副本反复失败后降级用 llama.cpp 模板重建),不至于在单一引擎上死循环。
  • 反向引用:训练详情页的"一键部署推理"按钮消费 GET /api/v1/nodes/{id}/inference-template 查询节点真正能跑的模板(同一套引擎选择逻辑的只读暴露,训练产出的 checkpoint 落盘后可直接部署成推理服务)。

七、API Key 生成与展示

机制说明
生成时机一键收录自动创建 Endpoint 时生成,格式 sk-{UUID}
存储形式库中仅存 sha256 哈希,明文无法找回
展示次数明文只在 POST /api/v1/models/discovered/add 的响应中出现一次,前端弹窗展示后不再可见
复用语义响应 reused=false 且 api_key 非空 = 新建服务;reused=true 且 api_key 为空 = 复用已有服务,Key 仍是首次创建时返回的那个
后续查看服务运行期的 Key 状态经推理服务页面的"API Key 查看"入口管理(见《推理服务》篇)

页面功能介绍

模型管理面板嵌入推理服务页面(仅平台管理员可见——后端写接口要求 system:write 权限,普通成员不渲染面板,避免展示点了就 403 的按钮)。

面板头部按钮

按钮行为调用 API
扫描模型(绿色)按钮变"扫描中...",展开扫描结果区,拉取全部可见节点的发现模型GET /api/v1/models/discovered
+ 添加模型 / 取消(蓝色)展开/收起手动添加内联表单—(提交时 POST /api/v1/models)
收起(扫描结果头部)隐藏扫描结果区(纯前端状态)—

手动添加表单

字段必填说明
模型名称是占位"例如: glm-5.1"
版本否占位"v1.0"
节点是下拉仅列 online/busy 节点,格式"节点名 (IP)"
模型路径是节点上的绝对路径,占位"/shared/models/glm-5.1"

必填为空时提交按钮半透明不可点击;成功后清空表单、收起并刷新模型列表。手动添加不会自动建服务。

扫描结果表

每行展示发现模型(名称/类型/大小/节点),状态列三色判定:

状态判定条件操作列
已添加(绿)已在注册表(added: true)"-"
未添加(黄)未注册,且节点引擎与模型格式兼容绿色"添加"按钮
不可用(红)未注册,但节点引擎不支持该格式"-"(悬停提示原因)

兼容性判定:GGUF 需要 llama-cpp/llamacpp 引擎;HuggingFace 需要 vllm/vllm-legacy/sglang 引擎;其他 format 一律视为兼容。点"添加"触发一键收录(POST /api/v1/models/discovered/add),成功后该行转"已添加"并刷新模型列表。

模型列表(8 列)

模型名称、来源(蓝"自动扫描"/灰"手动添加"标签)、类型、大小(GB/MB/KB 自适应,无数据显示"-")、节点(名 + IP)、路径(等宽字体超长截断)、智能路由、操作(红色"删除"按钮,二次确认后 DELETE /api/v1/models/{id})。

智能路由列依次渲染:用途徽标(绿"对话 (chat)"/"文本补全 (completion)"/"向量化 (embedding)",未标注为灰虚线框"用途未标注")→ 策略状态徽标(红"不参与"= 关闭了参与开关;蓝"自定义"= 改过权重;灰"默认参与"= 无策略行)→ "策略"按钮(打开编辑弹窗)。

策略编辑弹窗:参与智能路由开关(关闭 = 永不被 auto 选中,手动指定不受影响)、用途下拉(未标注/chat/completion/embedding)、质量/速度/成本三个权重输入(0-100 整数,前端校验)、"恢复默认"(删除策略行,回到默认——已标注的用途也会被清掉)。保存 PUT /api/v1/models/routing-policies/{name},恢复默认 DELETE 同一地址。

策略加载失败态:拉取策略失败(不阻塞模型列表)时,路由列显示橙色"策略未知"徽标与"重试"按钮,并禁用编辑——不按"全部默认"显示,避免把被设为"不参与"的模型误显示成"默认参与",也避免弹窗按默认值初始化后一保存覆盖真实策略。

按对外模型名设置用途/策略:表格行来自模型注册表,而策略按推理服务对外模型名(请求体 model 字段)生效——创建服务时自定义过对外名的模型在表格里没有对应行。面板底部为此提供独立输入区:输入对外名(带输入建议)→"编辑策略"打开同一弹窗;已设策略但注册表无同名行的对外名单独列出可再编辑。名字恰为保留名 auto 时前端直接提示不发请求;含 / 的对外名(HF 风格 org/name)自动改走 ?name= 查询形式(路径段里的 %2F 会被解码成路径分隔符)。策略按租户存储:平台管理员在"查看租户"选中某租户时,面板读写的都是该租户的策略。

后端逻辑概念表

概念含义
ModelInfo模型注册表行:模型名 + 节点 + 路径的元数据三元组,带租户归属
DiscoveredModel / ModelScannerAgent 扫描发现的一个模型(名称/路径/大小/format/model_type),随心跳上报;扫描器启动全量 + 每 12 次心跳增量(mtime 对比),状态持久化 .scan-state.json
DiscoveredModelsCacheServer 侧汇聚各节点上报的发现结果,GET /models/discovered 的数据源
引擎可用性探测Agent 每 20 次心跳重探 Docker 镜像/pip 包并无条件回灌路由器,inference_engines 随心跳上报
精确匹配裸 tag镜像判定规则:本地必须存在与模板完全同名同 tag 的引用,私仓前缀副本不判可用
模板链(DefaultInferenceTemplates)vllm→sglang→llamacpp 的默认引擎优先序,按节点可用性 + 算力顺序选定
MinGPUCC / ExplicitOnly模板最低算力门槛(vLLM 为 7.0,P100 被拦落 llama.cpp)/ 仅可显式指定的条目(trtllm),自动路径跳过
autoCreateInferenceService一键收录的后端执行体:选引擎 → 建组/端点/任务/路由的完整编排,失败回滚
inference_templates模板链写入 TaskGroup 的副本,恢复循环据此跨引擎 fallback 重建
ModelRoute对外模型名到推理服务的流量映射,priority 分组 + weight 加权 + 健康降级
resolveRoutingModelName / ensureModelRoute路由模型名裁决(优先 model_name 回退服务名)/ 复用服务组时按(租户, 模型名)幂等补建路由
模型级路由策略 / purposemodel=auto 下按模型名的参与开关 + 用途 + 三权重,按(租户, 模型名)存储;purpose 为用途标签(chat/completion/embedding/未标注)
(租户, 模型) 咨询锁一键创建的跨实例串行化(advisory lock),防并发建出重复服务
sha256 Key 落库API Key 明文只在创建响应出现一次,库中只存哈希

API 参考

模型接口均需 JWT 认证:读操作要求 nodes:read,写操作(创建/更新/删除/一键收录/策略写入)要求 system:write(即平台管理员)。路由策略支持平台运营者以 ?tenant_id= 代其他租户配置。

发现列表

GET /api/v1/models/discovered
{
  "code": 0,
  "data": [
    {
      "name": "qwen2-7b",
      "path": "/data/heteroflow/model-cache/qwen2-7b",
      "node_id": "node-1",
      "node_name": "gpu-node-1",
      "node_ip": "192.168.1.10",
      "size_bytes": 15000000000,
      "format": "huggingface",
      "model_type": "qwen2",
      "available_engines": ["vllm", "llama-cpp"],
      "added": false
    }
  ]
}

仅返回可见且在线节点的结果;available_engines 是前端兼容性判定与一键建服务选引擎的依据。

一键收录(含自动建服务)

POST /api/v1/models/discovered/add
Content-Type: application/json

{ "name": "qwen2-7b", "node_id": "node-1", "path": "/data/heteroflow/model-cache/qwen2-7b" }
{
  "code": 0,
  "data": {
    "model": { "id": "…", "name": "qwen2-7b", "source": "auto", "…": "…" },
    "inference": {
      "task_group_id": "tg-xxxx",
      "api_key": "sk-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "reused": false
    }
  }
}

inference.error 非空表示服务未建成(模型注册本身成功),附 error_code(quota_exceeded / tenant_inactive / endpoint_name_conflict)与 http_status。返回的 api_key 是明文 Key 的唯一一次出现,请立即保存。

模型级路由策略

GET    /api/v1/models/routing-policies            # 列出策略行(可带 ?tenant_id=)
PUT    /api/v1/models/routing-policies/{name}     # 写入/覆盖某模型策略
DELETE /api/v1/models/routing-policies/{name}     # 删除(回到默认,用途回到未标注)
GET/PUT/DELETE /api/v1/models/routing-policies?name=…   # 名字走 query(含 "/" 的对外名必须用这种形式)

PUT 请求体(部分更新,未知字段 400):

{ "routing_enabled": true, "quality_weight": 80, "speed_weight": 40, "cost_weight": 50, "purpose": "chat" }

权重须为 0-100 整数(越界 400);purpose 取 chat / completion / embedding,null 清除为未标注,不传沿用当前值。带 / 的对外模型名(如 Qwen/Qwen2.5-7B)在路径形式下返回 400,须用 ?name=(优先于路径段)。

模型 CRUD 与手动路由

接口方法说明
/api/v1/modelsGET / POST列表(可按 node_id、source 过滤)/ 手动注册
/api/v1/models/by-name?name=GET按名查询,返回全部同名(跨节点)
/api/v1/models/{modelID}GET / PUT / DELETE详情(UUID 或名称)/ 更新 / 删除
/api/v1/model-routesGET / POST路由列表 / 手动创建(约束见第四节)
/api/v1/model-routes/{id}PUT / DELETE更新权重/优先级 / 删除
/api/v1/nodes/{id}/inference-templateGET节点当前可用的推理模板选项(引擎选择逻辑只读暴露)

已知边界

1. 成本权重是占位:cost 策略与 cost_weight 目前没有真实价格数据支撑,只按静态权重排序;计价能力另行立项。

2. 智能路由默认关闭:model=auto 是 opt-in,需在推理控制面板开全局开关;存量模型用途全部"未标注",不标注则 auto 不按用途区分(选路与引入用途前一致)。

3. SGLang 在部分环境不可用:L20 + 驱动 580 环境官方镜像缺 nvcc、flashinfer JIT 必然失败;模板链已把链首选回 vLLM,SGLang 保留在链中供显式指定或仅装 SGLang 的节点。

4. 内网私仓镜像不被识别为可用:引擎探测精确匹配裸 tag,只有私仓前缀副本时需手动 docker tag 成裸引用(Agent 打 WARN 日志给出提示命令)。

5. 手动注册不建服务:POST /api/v1/models 只登记元数据,自动建服务仅"扫描发现 + 一键收录"路径触发。

6. 端点重名时模型注册与建服务结果分离:endpoint_name_conflict 下模型行已落库、服务未建,整体响应仍为 200——调用方必须检查 inference.error,不能只看 HTTP 状态码。

7. API Key 明文不可找回:库中仅存 sha256 哈希,遗失只能删除端点重建服务。

8. 删除模型不级联:删除注册行不影响已建推理服务、端点与路由;删除服务也不清理模型行,两边各自管理。

9. 扫描目录配置是替换语义:配置 model_scan_dirs 后默认缓存目录失效(/data/models 除外,始终扫描)。

10. Transformers 已退役:2026-10-02 起各入口 400、存量任务显式失败,从未提供过真推理服务。

<!-- 状态标注说明:本文能力状态口径——"真机验证"指在真实 GPU 节点端到端运行并确认(引擎探测与一键建服务在 NVIDIA T4/P100/A10/A800/L20 等节点反复验证,P100 落 llama.cpp 兜底为真机结论);"已实现"指代码合入且有单元/集成测试覆盖但未做真机端到端。功能口径与平台《模型管理》《推理服务架构与功能详解》文档及 capability-tree A12/A10.3-A10.5 一致;路由决策在网关的执行细节(负载均衡、灰度、会话粘性、限流)见《推理网关》篇,服务生命周期(休眠唤醒、自动伸缩、滚动更新)见《推理服务》篇。 -->