6.0 KiB
6.0 KiB
id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week, order
| id | title | type | domain | stack | tags | level | prerequisites | est_hours | related | week | order | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ai.llm-serving.routing-vllm-lora | 模型侧基础:多模型接入和路由、vLLM 部署、LoRA / QLoRA 概念 | lesson | ai |
|
|
intermediate |
|
3 |
|
|
1 |
模型侧基础:多模型接入和路由、vLLM 部署、LoRA / QLoRA 概念
本课定位是了解级:应用开发岗位面试会问到“模型怎么接、怎么部署、什么时候微调”,能讲清楚原理和取舍即可,不要求会训练模型。vLLM 等工具参数变化快,以官方文档为准:https://docs.vllm.ai/
解释说明
1. 多模型接入和路由
企业里通常同时使用多个模型:不同厂商的大模型、便宜的小模型、自部署的开源模型。统一接入层(自建网关或 LiteLLM 这类开源网关)负责:
| 功能 | 说明 |
|---|---|
| 统一接口 | 大多数厂商和 vLLM 都提供 OpenAI 兼容接口,业务代码用同一套 SDK,只换 base_url 和模型名 |
| 按任务路由 | 分类、改写用小模型;复杂推理用大模型;敏感数据只走自部署模型 |
| 超时、重试 | 限流(429)退避后重试;故障 / 超时换下一个提供方 |
| 熔断 | 某个提供方连续失败时暂时跳过,冷却后试探 |
| 降级 | 主模型不可用时切备用;都不可用时返回友好提示 |
| 配额和成本 | 按业务方 / 用户限额;记录每次调用的 token 和成本 |
| 密钥管理 | 业务方不直接持有厂商密钥 |
2. vLLM 部署基础
vLLM 是常用的开源大模型推理服务框架:
- 核心技术:PagedAttention(像操作系统分页一样管理 KV 缓存,减少显存浪费)和连续批处理(请求随到随加入批次),吞吐量高。
- 启动:
vllm serve <模型名或路径>,默认在 8000 端口提供 OpenAI 兼容接口(/v1/chat/completions)。 - 常用参数:
--tensor-parallel-size(多卡切分)、--max-model-len(最大上下文,影响显存)、--gpu-memory-utilization(显存占用比例)、--quantization(量化)。 - 显存粗估:参数量 × 每个参数的字节数(FP16 为 2 字节),7B 模型权重约 14GB,另外还需要 KV 缓存空间;量化到 4 bit 后权重约 4GB 左右。
- 同类工具:SGLang、TGI、Ollama(本地体验)、llama.cpp。
自部署的理由:数据不能出内网、调用量很大时成本更低、需要定制模型。代价:GPU 成本、运维、模型效果通常不如顶级商用模型。
3. 微调和 LoRA / QLoRA(概念)
| 方法 | 说明 |
|---|---|
| 全量微调 | 更新全部参数,效果上限高,显存和数据要求高 |
| LoRA | 冻结原模型,只训练插在部分层上的低秩矩阵(W + BA,A、B 很小),可训练参数通常不到 1%;训练好的“适配器”文件很小,可以一个底座挂多个适配器 |
| QLoRA | 把底座模型量化到 4 bit 再做 LoRA 训练,进一步降低显存,单张消费级显卡也能微调中等规模模型 |
什么时候需要微调? 先用提示词 + RAG;当需要固定的输出风格 / 格式、特定领域的表达、用小模型替代大模型降低成本,并且有足够的高质量标注数据和评测集时,才考虑微调。知识更新类需求用 RAG,不用微调。
案例
公司客服系统:意图分类走便宜的小模型;答案生成走商用大模型,备用另一家厂商;涉及员工身份证、薪资的问题只走内网 vLLM 部署的开源模型。一次主厂商故障,网关在 3 次失败后熔断,自动切到备用厂商,用户基本无感;事后看台账,降级期间成本上升了,但服务没有中断。
代码示例
路由、重试、熔断、降级、成本台账(完整版本 examples/model-router/router.py,只用标准库):
async def chat(self, task, messages):
errors = []
for name in self.routes[task]: # 按优先级尝试提供方
p, br = self.providers[name], self.breakers.setdefault(name, Breaker())
if not br.allow():
continue # 熔断中,跳过
for attempt in range(self.max_retries + 1):
try:
r = await p.call(messages, self.timeout)
except RateLimited:
await asyncio.sleep(0.01 * 2 ** attempt) # 限流:退避后重试同一个
continue
except (ProviderDown, asyncio.TimeoutError):
br.record(False)
break # 故障 / 超时:换下一个
br.record(True)
return r
raise RuntimeError("所有模型都不可用")
调用自部署的 vLLM(OpenAI 兼容接口,示意):
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="token-local") # vLLM 可用 --api-key 设置
resp = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "你好"}],
)
print(resp.choices[0].message.content)
易错点
- 业务代码直接依赖某个厂商的 SDK 特有功能,换模型时大面积修改。
- 所有错误都重试:参数错误、内容审核拒绝重试也没用。
- 降级到备用模型后不记录、不告警,效果下降没人知道。
- 自部署模型的成本只算 token 为 0,忘了 GPU 和运维成本。
--max-model-len设得过大导致显存不足启动失败,或者并发能力很低。- 把微调当成“让模型学会公司知识”的方法:知识更新用 RAG。
面试常问
- 怎么同时接入多家模型?怎么做降级?
- vLLM 为什么快?
- LoRA 是什么?什么时候需要微调?