完全指南:零客户端改动的模型重定向与灰度切换)
LocalAI 模型别名Model Aliases完全指南零客户端改动的模型重定向与灰度切换【免费下载链接】LocalAILocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required.项目地址: https://gitcode.com/GitHub_Trending/lo/LocalAIModel Aliases模型别名是 LocalAI 提供的一种纯重定向模型配置以一行 YAML 声明“别名 → 目标模型”的映射所有访问别名的客户端流量会被自动转发给目标真实模型处理。本文面向需要在不改动客户端代码的情况下切换底层模型的部署工程师讲解别名的声明语法、运行规则、管理 API以及它在分布式模式中作为“部署槽位deployment slot”承载调度规则的进阶用法并深入到 core/config/model_config.go 与 core/http/middleware/request.go 等源码说明别名的校验、解析与全模态生效的底层原理。什么是模型别名一个model alias模型别名是一个“把全部流量重定向到另一个已配置模型”的模型名。例如把gpt-4声明为my-llama-3的别名后每个以gpt-4名义发起的调用都会由my-llama-3实际服务客户端无需任何重新配置客户端继续使用它们熟悉的模型名gpt-4服务端由你掌控“哪个模型在回答这个名字”底层模型想换就换切换过程对调用方完全透明。在源码中别名就是 ModelConfig 结构体的Alias字段// Alias, when set, makes this config a pure redirect: every request for // Name is served by the model named here. All other fields are ignored. // The target must be an existing, non-alias model (enforced at load and // at create/swap time). Alias string yaml:alias,omitempty json:alias,omitempty注意注释中的关键定语pure redirect纯重定向一旦配置了alias该配置里的其余字段都会被忽略。声明一个别名在 LocalAI 的模型目录models directory中创建一个极简配置文件即可例如文件名gpt-4.yamlname: gpt-4 alias: my-llama-3这份配置就完成了全部工作name客户端实际调用的别名对外暴露的名字alias真正承接请求的目标模型名。整个配置文件只有这两个字段。目标模型my-llama-3必须在别处已经以一份正常非别名配置存在——它带有自己的backend、parameters.model或model、context_size等完整加载参数。别名的职责仅仅是“指路”不携带任何模型加载信息。LocalAI 的模型配置文件加载逻辑会扫描整个模型目录并统一建索引相关实现可参考 core/config/model_config_loader.go。也可以把多个别名配置文件放入同一个 models 目录例如同时提供gpt-4、gpt-4-turbo、claude-3三个名字各自指向本地不同模型实现“一个 OpenAI 兼容接口背后接不同本地模型”的多租户入口。规则与行为约束LocalAI 对别名有一整套明确、强制的运行规则其中大多数由加载器与校验逻辑在代码层面落实目标必须真实存在、非别名、且启用不能指向一个缺失的模型、被禁用的模型disabled: true或另一个别名。链式别名别名指向别名被明确禁止。这一点在ResolveAlias中有严格实现见下文。1:1 映射一个别名恰好映射到一个目标反之一个目标模型可以被多个别名引用。目标可热切换live swap通过编辑配置文件、调用 API、使用 Web UI 或让 LocalAI Assistant 代劳都可以随时改指目标无需重启服务。GET /v1/models同时返回两者gpt-4别名和my-llama-3真实模型都会出现在模型列表中。响应回显请求的别名调用gpt-4得到的响应中model字段是gpt-4而不是目标名my-llama-3。用量统计双记录同时记录 requested请求方叫gpt-4与 served实际服务方my-llama-3两侧信息。全模态生效chat、embeddings、audio、image 等所有模态的请求都会继承这一重定向逻辑。全模态继承的实现原理“别名对每个模态都生效”并不是在每种模态的处理器里各自实现一遍而是在请求管线的最前端统一完成。在 core/http/middleware/request.go 的请求中间件中LocalAI 对已解析出配置的请求执行一次别名解析// Resolve a model alias to its target before the disabled check and // before storing MODEL_CONFIG, so every modality (chat, embeddings, // tts, image, ...) inherits redirection. The response keeps echoing // the alias name (input.ModelName is left unchanged); usage accounting // records requestedalias / servedtarget. if cfg ! nil cfg.IsAlias() { resolved, _, aliasErr : re.modelConfigLoader.ResolveAlias(cfg) if aliasErr ! nil { return c.JSON(http.StatusBadRequest, ...) } c.Set(ContextKeyRequestedModel, modelName) c.Set(ContextKeyServedModel, resolved.Name) cfg resolved }解析发生在“禁用检查”之前、上下文写入MODEL_CONFIG之前。别名解析后请求上下文会被同时打上两个标签ContextKeyRequestedModel请求方的名字与ContextKeyServedModel真实服务模型的名字而input.ModelName保持不变——这正是响应回显别名、而实际由目标模型服务、并且用量统计能分别记账的实现基础。解析器与校验逻辑别名相关的核心逻辑集中在 core/config/model_config_loader.go三个函数各有分工ResolveAlias严格模式的一跳解析。若配置是别名则查找目标目标不存在返回alias %q points to unknown model %q目标本身是别名则返回alias %q points to another alias %q (chains are not allowed)。非别名配置原样返回。ResolveAliasName把模型名映射为真正提供服务的模型名别名解析到目标、其余名字映射到自身且永不报错——对于没有配置的名字、悬空别名、链式别名都解析回自身保证调度规则等在模型尚未安装时仍能持有可用名字。ValidateAliasTarget在“创建/改指目标”的时刻校验目标必须存在、不能是别名、不能被禁用。此外LoadResolvedModelConfig在按名加载配置后会跟随一次别名跳转保证下游例如 pipeline 引用llm: default别名、分布式模式等场景拿到的是目标模型的完整配置含Backend、Model等而非一个Backend为空的“别名占位符”避免在分布式模式下出现backend name is empty之类的下游失败。加载器在扫描完模型目录后还会对悬空/链式别名打印告警日志参见 core/config/model_config_loader.go 中的别名健全性检查逻辑。别名的配置校验为什么“纯重定向”不可被污染alias字段的注释强调“所有其他字段被忽略”LocalAI 在校验阶段用强约束保证了这一点。ModelConfig.Validate 对别名配置执行如下规则// An alias is a pure redirect: validate only its own shape here. Target // existence and the no-chain rule need the full config set, so the loader // (load-time) and the create/swap endpoints enforce those. if c.IsAlias() { if c.Name { return false, fmt.Errorf(alias config requires a name) } if c.Alias c.Name { return false, fmt.Errorf(alias %q cannot point to itself, c.Name) } if c.Backend ! || c.Model ! { return false, fmt.Errorf(alias config %q must not set backend or parameters.model: an alias is a pure redirect, c.Name) } return true, nil }同时校验逻辑 还禁止别名声明artifactsalias model %q cannot declare artifacts。目标存在性、非别名、不禁用这类需要“看到全量配置集合”才能判断的约束则留给加载器load-time与创建/改指接口在运行时执行。这一组约束共同保证了别名始终是一个合法、干净的重定向不会有配置漂移导致的行为不一致。管理别名四种操作入口你可以从任何管理面创建、改指、删除别名。1. 静态配置文件直接编辑模型目录中的 YAML见上文“声明一个别名”保存后即可热生效。2. Web UI打开Add Model添加模型面板选择Alias / Routing模板填写name对外别名与 target目标模型。若要给已有别名重新定向编辑该配置并修改目标模型即可。3. REST APILocalAI 为别名提供了一组 HTTP 管理接口操作端点说明创建POST /models/import以 YAML/JSON 配置体导入一个新的别名配置改指目标PATCH /api/models/config-json/:name更新指定别名的配置实现热切换live swap列出全部别名GET /api/aliases返回所有别名及其目标删除POST /models/delete/:name删除某个别名配置GET /api/aliases的实现见 core/http/endpoints/localai/aliases.go遍历全量模型配置仅挑出IsAlias()为真的条目以name/target对的形式返回空结果序列化为[]而非null。其测试 aliases_test.go 验证了种子一个真实模型real与一个别名gpt-4 - real后接口只返回gpt-4别名条目真实模型本身不会作为别名出现在列表中。4. LocalAI Assistant 与 MCPLocalAI Assistant以及 MCP server把这些操作暴露为同名工具set_alias设置/改指别名、list_aliases列出别名、delete_model删除模型。也就是说管理员可以直接用自然语言指示助手“把gpt-4指到新模型上”。重要限制不能把真实模型“改装”成别名你无法把一个已经存在的真实模型变成别名。如果对某个已经是真实非别名模型的名字执行set_alias或PATCH /api/models/config-json/:name该请求会被拒绝。原因正是前文所述的“纯重定向”语义别名是纯重定向因此不能携带backend或parameters.model而真实模型必然带有backend/parameters.model把alias合并进真实模型会产出一个“既有加载参数、又是重定向”的非法配置校验会以alias config ... must not set backend or parameters.model报错拒绝。这是有意设计防止一次误操作的set_alias意外覆盖掉一个正在提供服务的真实模型。因此新增别名用一个新名字指向目标而不是复用现有模型的名字改指已有别名完全支持且这正是 live-swap 的标准路径——别名配置自身没有 backend改指目标后它依然是一个合法的纯重定向。进阶把别名当作分布式模式的“部署槽位”在 distributed mode分布式模式 中别名可以携带一条调度规则。POST /api/nodes/scheduling接受别名作为model_name规则将约束该别名当前所指向的模型curl -X POST http://frontend:8080/api/nodes/scheduling \ -H Content-Type: application/json \ -d {model_name: production, node_selector: {tier: gpu}, min_replicas: 2}这条规则的语义是所有解析到名为production这一模型名即其当前目标模型的副本都必须放置在tiergpu的节点上且至少维持 2 个副本。之后你只需重新定向production别名放置策略就会跟随新的目标模型——于是别名表现为一个内容可随时更换的稳定槽位stable slot。例如先让production指向qwen3-7b调度规则落在一批 A100 节点上完成压测压测结束把production改指qwen3-14b无需改动任何调度规则新的更大模型自动继承同一套tiergpu、min_replicas2的部署策略。由于一个副本会被所有解析到它的名字共享同一个模型在同一时刻只能被一条规则治理。写入路径会拒绝冲突对已被别名规则覆盖的目标模型再提交规则、或对一个已有自身规则的真实模型提交指向它的别名规则都会收到409 Conflict规则中列出的同名规则会标记为shadowed被遮蔽。这些行为由 core/services/nodes/alias_scheduling.go 的别名解析器配合节点注册表实现并在 nodes_scheduling_alias_test.go 中完整覆盖包括“接受别名规则并回显其治理的模型”“拒绝同一模型的第二条规则”“拒绝覆盖已有自身规则的别名规则”“允许原地编辑规则”“拒绝解析不出的孤儿别名”等用例。值得注意的是调度系统允许规则先于模型安装存在对一个“尚未安装”的模型名提交规则会成功——这与ResolveAliasName永不报错的设计一脉相承详见 docs/content/features/distributed-mode.md 中 Scheduling a model alias 一节。边界别名的定位与更复杂路由的选择模型别名的定位是静态的 1:1 重定向。如果需求是基于分类器classifier自动选择下游模型在多个下游模型之间做负载均衡load-balanced选择则应当使用 Middleware智能路由器 功能中的 router 能力而不是别名。别名适合“一个固定名字、指向一个真实模型、需要随时整体换掉目标”的场景路由器适合“一个入口、背后一群模型、按规则分流的场景”两者是互补而非替代的关系。小结能力别名相关源码/文档声明方式models 目录下 YAMLnamealiasmodel_config.go全模态生效请求中间件统一解析middleware/request.go严格一跳解析目标须存在、非别名、启用model_config_loader.go列出别名GET /api/aliasesendpoints/localai/aliases.go分布式部署槽位调度规则可跟随别名目标nodes_scheduling_alias_test.go动态分流/负载均衡使用智能路由器docs/content/operations/middleware.md使用模型别名的核心收益一句话概括把“对外暴露的模型名”与“真正在跑的模型”解耦——客户端永远只认识gpt-4这样的稳定名字而服务端可以随时通过编辑配置、调用 API、操作 Web UI 或让 Assistant 代劳来热切换其背后的真实模型无论是做兼容性入口、A/B 切换还是分布式部署灰度都不再需要触碰任何一行客户端代码。若想进一步了解别名与 Web UI、Assistant 集成的完整交互细节可参考 docs/content/features/localai-assistant.md 与 docs/content/features/mcp.md本文源文档位于 docs/content/features/model-aliases.md。【免费下载链接】LocalAILocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required.项目地址: https://gitcode.com/GitHub_Trending/lo/LocalAI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考