--- id: ai.llm-serving.routing-vllm-lora title: 模型侧基础:多模型接入和路由、vLLM 部署、LoRA / QLoRA 概念 type: lesson domain: ai stack: [llm-serving] tags: [多模型路由, OpenAI 兼容接口, 降级, 熔断, vLLM, 量化, LoRA, QLoRA, 微调] level: intermediate prerequisites: [python.asyncio.concurrency-control] est_hours: 3 related: [ai.agent-ops.observability-cost, ai.llm-serving.scenario.multi-provider-gateway, ai.llm-serving.interview] week: [10, 13] order: 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](examples/model-router/router.py),只用标准库): ```python 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 兼容接口,示意): ```python 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 是什么?什么时候需要微调?