文章

LLM LoRA Adapter 缓存生产实战:用热度分层、冷启动预算与驱逐策略稳住多租户微调服务

在多租户微调服务中,LoRA Adapter 数量、版本与租户数持续增长,单纯全量预加载已不可行。本文从 Adapter Registry、热度分层、冷启动预算、驱逐策略到上线检查,系统讲解如何构建生产级 Adapter 缓存治理体系,帮助团队在共享基础模型池中稳定服务大量定制模型。

背景问题:LoRA 让定制模型变轻,但没有消除服务治理

LoRA 的价值很清楚:基础模型保持不变,业务只训练一组较小的 Adapter 增量权重,即可得到面向客服、金融、代码、法务、运营等场景的定制能力。对训练和存储来说,这是很大的节省;对线上推理来说,问题只是被转移了。

当一个平台只有几个 adapter 时,最简单的做法是全部启动时加载。可是多租户场景下,adapter 很快会变成几十、几百甚至更多。每个租户可能有正式版、灰度版、回滚版、A/B 实验版;每个业务线可能还会按语言、行业、地区拆分。此时线上瓶颈不再是”能不能加载 LoRA”,而是:

  • 哪些 adapter 应常驻 GPU,哪些只放在 CPU 内存或对象存储;
  • 冷 adapter 被请求时,允许增加多少 TTFT(Time To First Token);
  • adapter 被驱逐后,正在运行的请求是否会受影响;
  • 相同 adapter 名称被更新时,如何保证版本一致性;
  • 热租户是否会挤掉冷门但高优先级租户的 adapter;
  • adapter 文件是否经过签名、格式校验和基座模型兼容校验。

因此,LoRA 生产化的核心不是再解释一次低秩矩阵,而是建立一套 Adapter Cache 管理层

核心原理:把 Adapter 当成独立资源,而不是模型参数的附属品

一个 LoRA 请求可以拆成三类资源:

资源类型说明加载成本生命周期
Base Model大模型完整权重,常驻 GPU 或由推理引擎管理最高最长
Adapter Weight体积远小于基础模型,数量多、版本多、访问分布高度倾斜中等按热度变化
Request Runtime StateKV Cache、队列位置、采样参数、streaming 状态和请求账本请求级别

生产系统中,Adapter Cache 至少需要三层:

1. GPU Hot Tier

GPU 热层保存当前高频 adapter。目标是让热请求不触发 adapter 加载,从而稳定 TTFT 和 P95/P99 延迟。

但 GPU 热层不能无限扩大。adapter 占用的显存会与 KV Cache、batch size、上下文长度、并发请求争资源。一个常见误区是把 GPU 利用率看成唯一指标——如果 adapter 占用过多,GPU 可能看起来很忙,但吞吐和尾延迟反而恶化。

2. Host Warm Tier

Host Warm Tier 通常位于 CPU 内存或本机 NVMe。它保存近期可能回温的 adapter,用于减少从远端对象存储下载、解压、校验和格式转换的成本。

这层适合保存”不是很热,但不能太慢”的 adapter,例如企业大客户、白名单租户、即将进入活动期的业务线、灰度发布中的新版本。

3. Artifact Cold Tier

Cold Tier 是对象存储、模型仓库或制品仓库。它必须保留完整版本、签名、元数据、训练血缘和兼容信息。任何 adapter 从 Cold Tier 进入线上,都要经过准入检查,而不是只看路径是否存在。

工程落地:从 Adapter Registry 开始,而不是从推理引擎参数开始

建立 Adapter Registry

Adapter Registry 是 LoRA 生产系统的控制面。每个 adapter 至少应有这些字段:

adapter_id: "tenant-a-support-v3"
base_model: "llama-3.1-8b-instruct"
version: "2026-07-09.1"
rank: 16
format: "peft"
artifact_uri: "s3://model-artifacts/lora/tenant-a-support/v3"
sha256: "..."
status: "active"
tenant_id: "tenant-a"
priority: "gold"
compatibility:
  tokenizer_revision: "..."
  target_modules: ["q_proj", "v_proj"]
  max_lora_rank: 32
release:
  canary_percent: 10
  rollback_to: "2026-06-30.2"

这张表的价值不只是查询路径。它决定 adapter 能否被加载、加载到哪个 base model、是否允许灰度、是否允许被驱逐、是否需要保留最小热副本。

设计热度分数,而不是简单 LRU

单纯 LRU 容易把”刚刚被突发访问的低价值 adapter”留在 GPU,把”低频但高 SLA 的关键 adapter”驱逐出去。更合理的做法是使用加权热度分数:

adapter_cache_policy:
  gpu_slots_per_base_model: 64
  host_slots_per_base_model: 2048
  eviction_policy: "weighted-lru"
  hot_score_formula: |
    0.45 * qps_10m +
    0.25 * ttft_penalty_if_cold +
    0.20 * tenant_priority +
    0.10 * scheduled_warmup_score
  never_evict_when:
    - status == "canary" and canary_percent > 0
    - tenant_priority == "platinum"
  demote_when:
    - no_request_for_minutes > 60
    - error_rate_after_load > 0.02

这里的关键是把请求频率、冷启动惩罚、租户优先级、业务预热信号放在一起。否则缓存策略会只服务平均吞吐,不服务业务目标。

给冷启动设预算

LoRA 冷启动包括:解析 adapter id、读取注册表、下载或定位文件、校验签名、加载到 host、搬运到 GPU、更新推理引擎内部映射。不同框架对这些动作的支持不同,但业务侧应该统一成一个冷启动预算。

建议至少设置三类预算:

预算类型适用场景策略
交互请求预算客服对话、代码补全、在线问答冷 adapter 不应直接进入主链路,可返回排队、降级到基础模型或提前预热
后台任务预算离线摘要、批量质检、数据标注可接受更长加载时间,但要限制并发冷加载数量
灰度发布预算新 adapter 进入用户流量前先用影子请求和黄金集预热,避免第一次真实访问触发完整冷启动

把动态加载放进受控通道

vLLM 支持 LoRA per-request 使用,也支持通过 API endpoint 或 resolver plugin 动态加载 adapter;TGI 支持在启动时通过环境变量声明多个 LoRA adapter,并在请求参数中指定 adapter。它们给了工程能力,但生产治理不能只依赖推理引擎开关。

生产系统应把动态加载封装为内部控制面:

业务请求 → LLM Gateway → Adapter Registry 查询
    → Adapter Cache Manager 决策
    → 推理引擎 load / pin / use
    → 请求完成后更新热度与成本账本

不要让外部租户直接传 adapter 路径,也不要允许未签名 adapter 直接进入推理进程。特别是远程下载能力,应只对受信环境开放,并配合 allowlist、签名校验、大小限制、格式检查和审计日志。

适用场景

这套方案适合以下场景:

  • 企业 SaaS 为每个客户维护定制客服模型;
  • 内部 AI 平台为不同团队提供同一基础模型上的多个 SFT/LoRA 版本;
  • 代码助手按语言、项目、团队风格加载不同 adapter;
  • 内容生产平台按品牌语气、市场区域、合规策略维护 adapter;
  • 多租户推理平台希望共享基础模型显存,同时提供定制模型入口。

如果你的系统只有一两个 adapter,且发布频率很低,不必一开始做复杂缓存层。先固定加载、固定发布、固定回滚即可。复杂度应来自真实增长,而不是架构想象。

常见误区

误区一:LoRA 很小,所以不用管显存

单个 adapter 小,不代表 adapter 集合小。多租户系统的 adapter 数量、版本数和 rank 差异会持续增长。GPU 热层过大,会挤压 KV Cache 和 batch 空间。

误区二:LRU 足够解决驱逐问题

LRU 只代表最近访问,不代表业务优先级、冷启动代价或 SLA。生产环境要把租户等级、灰度状态、活动预热、错误率和加载成本纳入策略。

误区三:动态加载等于生产可用

动态加载是能力,不是治理。没有签名校验、版本锁定、路径隔离、审计和回滚机制,动态加载会变成线上风险入口。

误区四:只监控基础模型指标

LoRA 服务必须按 adapter 维度看指标。否则你只能看到整体 GPU 利用率,却看不到某个 adapter 的冷启动次数、加载失败率、命中率和版本漂移。

上线检查清单

上线前建议逐项检查:

#检查项说明
1注册表完整性每个 adapter 是否绑定 base model、rank、格式、target modules、版本和 sha256
2加载安全是否禁止任意路径加载,是否只允许可信仓库和签名制品
3缓存分层是否区分 GPU hot、host warm、artifact cold
4驱逐保护灰度、白名单、高 SLA adapter 是否有最小驻留或预热策略
5冷启动预算交互请求、后台任务、灰度请求是否使用不同预算
6版本一致性同一 adapter 名称更新时,正在运行请求是否继续使用旧版本,还是允许原地替换
7指标维度是否按 base_model、adapter_id、tenant_id、adapter_version 输出命中率、加载耗时、加载失败率、TTFT、P95/P99
8回滚路径adapter 失败时能否回滚到上一版本,或降级到基础模型
9压测场景是否覆盖热 adapter、冷 adapter、突发加载、批量驱逐、仓库不可用、签名失败

总结

LoRA Adapter 缓存治理是多租户微调服务的核心工程挑战之一。它不是 GPU 显存管理的附属问题,而是一个需要独立设计的控制面系统。核心要点回顾:

  1. 三层缓存架构:GPU Hot → Host Warm → Artifact Cold,按热度逐级降级;
  2. 加权热度分数替代 LRU:融合请求频率、冷启动惩罚、租户优先级和业务预热信号;
  3. 冷启动预算分类管理:交互请求、后台任务、灰度发布使用不同预算和降级策略;
  4. 受控加载通道:所有动态加载必须经过 Registry 校验,禁止租户直接传路径;
  5. 按 adapter 维度监控:从命中率到 P99 延迟,都要能下钻到单个 adapter。

如果你的多租户 LoRA 服务正在从”几个 adapter 全量加载”向”几十上百个 adapter 按需调度”过渡,现在就是建立这套治理体系的最佳时机。

参考资料

常见问题

LoRA Adapter 缓存和普通模型缓存有什么区别?
普通模型缓存通常围绕完整权重或推理实例,LoRA Adapter 缓存围绕共享基础模型上的小型增量权重,重点是按 adapter 维度治理热度、加载、驱逐和版本一致性。
只把所有 LoRA Adapter 预加载到 GPU 上可以吗?
小规模可以,但当 adapter 数量、rank、租户数和版本数上升后,GPU 显存会被 adapter 挤占,影响 KV Cache、batch size 和尾延迟,需要热度分层与驱逐策略。
动态加载 LoRA Adapter 是否适合直接暴露给外部租户?
不建议直接暴露。生产环境应通过受控注册表、签名校验、灰度准入和租户授权来管理动态加载,避免任意路径加载和未审计权重进入推理进程。
LoRA Adapter 缓存应该由网关做,还是由推理引擎做?
两者都要参与。推理引擎负责实际加载、执行和内部显存管理;网关或控制面负责租户策略、版本准入、预热计划、驱逐优先级和审计。不要把业务策略全部塞进推理引擎参数。