1. 大模型推理扩容为什么不能照搬微服务那套大模型推理服务的弹性扩容指的是在请求量波动时自动增减推理实例、并让 GPU 资源始终匹配负载的一套机制。它和普通 Web 服务的扩容完全不是一回事。普通微服务扩容拉起新 Pod、注册到注册中心5 到 10 秒就能接流量而大模型推理 Pod 启动后得先把几 GB 到上百 GB 的模型权重从磁盘搬进 GPU 显存7B 模型大约 30 秒70B 模型两分钟起步。这段时间里 Pod 是活着但不能干活的状态Kubernetes 原生的就绪探针根本分不清进程起来了和模型加载完了。我见过太多团队直接拿默认 HPA 套在推理服务上结果流量洪峰过去十分钟了新 Pod 才刚把权重加载完扩容等于白扩。更麻烦的是 GPU 是独占资源一张卡被一个 Pod 占住剩下的 CPU 和内存别人也用不了集群里很快堆出一堆半张卡的碎片。再加上 HPA 默认 15 秒采一次指标、按过去 1 到 5 分钟均值决策对脉冲式流量天然滞后。所以真正能打的方案得同时解决三件事冷启动、GPU 碎片、指标滞后。下面这套架构我在生产里跑过核心思路是预测性扩容 温备池 GPU 拓扑感知调度三层配合再叠加 TaoToken 统一通道把多模型接入和配额管理收口避免每个模型各配一套 Key 和限流逻辑。适合谁看正在把大模型推理往 Kubernetes 上搬、被扩容延迟和 GPU 利用率折磨的后端或平台工程师。你需要对 HPA、自定义指标、Kubernetes 调度有基本概念代码部分我会给到能直接改的片段。先说清楚整体数据流请求先进网关网关把请求投进队列指标采集器从队列和推理实例上抓队列深度、首 Token 延迟TTFT、GPU 显存利用率增强型 HPA 控制器综合这些指标和流量预测器的结果做扩容决策决策分两路一路让温备池管理器激活已预加载模型的温备 Pod一路让 GPU 拓扑感知调度器去冷备节点上拉起新 Pod。温备 Pod 激活只需注册路由秒级完成冷备 Pod 走完整加载流程分钟级。两条路并行才能既快又不丢容量。这里有个关键认知预测性扩容不替代响应式 HPA而是补充。可预见的周期流量每天晚高峰、每周促销靠预测提前 5 分钟扩突发流量靠响应式 HPA 兜底。两者叠加才能把扩容响应时间压下来。2. TaoToken 统一通道在多模型扩容里的位置多模型推理集群最容易被忽视的坑不是 GPU 不够而是接入层失控。你集群里可能同时跑着 7B 的对话模型、13B 的代码模型、还有 embedding 模型每个模型如果各自维护一套 API Key、各自的限流、各自的配额统计扩容时你根本说不清到底是哪个模型的流量把 GPU 打满了。TaoToken 在这里的角色是把多模型接入收敛成一个统一 Key 和统一 API 通道让扩容决策有干净的指标来源。TaoToken 是一个大模型 API 统一接入通道能做什么用一个 Key 访问多家模型统一计费和配额管理适合需要在多个模型间切换、又不想为每个模型单独维护鉴权体系的团队。适合谁正在做多模型推理服务、需要按模型维度做限流和成本核算的平台团队。它的接入地址是https://taotoken.net/api官网在https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。注意 API 地址不带 UTM 参数直接用于代码里的 Base URL。为什么扩容场景要引入它因为当你的推理服务前面挂的是统一通道时通道侧的请求计数、按模型的 QPS、错误率天然就是扩容指标的补充来源。你可以把通道侧的某模型请求排队数和集群侧的队列深度对齐判断扩容是该加实例还是该调通道限流。反过来如果每个模型各走各的 Key指标口径对不齐扩容阈值就没法统一设。具体到操作你需要在 TaoToken 控制台创建一个 API Key然后在推理服务的网关层把上游地址指向 TaoToken 的 API 端点。这样网关转发请求时鉴权、路由、配额都由通道统一处理你的 HPA 只需要关心集群内部的队列深度和 TTFT。控制台入口在https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Key 管理在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite。有一点要提醒TaoToken 是接入通道不是推理引擎它不负责你的 GPU 调度。GPU 池化、HPA、温备池这些还是在你自己的 Kubernetes 集群里做。通道解决的是多模型怎么统一接、统一算账集群解决的是算力怎么弹性给。两者职责别混。如果你还在选型阶段想先验证某个模型在通道上的延迟表现可以直接用模型对话页面测一下https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite。长期跑编码类或 Agent 类负载的可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite。接入细节文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite。3. 可复制的 HPA 配置与 GPU 池化参数这一节给能直接落地的配置。先说增强型 HPA核心是把扩容指标从 CPU 利用率换成队列深度、TTFT、GPU 显存利用率这三个业务指标。为什么不用 CPU因为 GPU 推理时 CPU 大部分时间在等 GPUCPU 利用率上不去但请求已经排长队了。apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: llm-inference-hpa namespace: ai-production spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: llm-inference-server minReplicas: 2 maxReplicas: 10 metrics: - type: Pods pods: metric: name: inference_queue_depth target: type: AverageValue averageValue: 10 - type: Pods pods: metric: name: inference_ttft_seconds target: type: AverageValue averageValue: 2 - type: Pods pods: metric: name: gpu_memory_utilization target: type: AverageValue averageValue: 85 behavior: scaleUp: stabilizationWindowSeconds: 30 policies: - type: Pods value: 2 periodSeconds: 60 scaleDown: stabilizationWindowSeconds: 300 policies: - type: Pods value: 1 periodSeconds: 120三个指标的含义队列深度超过 10 说明实例处理不过来请求在排队TTFT 超过 2 秒说明 GPU 算力不足用户体验已经受损显存利用率超过 85% 说明 KV Cache 接近上限再加并发就 OOM。扩容策略用 30 秒稳定窗口、每次最多加 2 个 Pod缩容用 300 秒窗口、每次只减 1 个避免流量抖动导致反复扩缩。接下来是 GPU 池化的关键参数。GPU 池化指的是把集群里不同型号、不同节点的 GPU 抽象成一个可调度资源池让推理 Pod 按需申请。核心是给节点打标签让调度器能识别 GPU 型号和拓扑。apiVersion: v1 kind: Node metadata: name: gpu-node-a100-01 labels: nvidia.com/gpu.product: A100-SXM4-80GB gpu.topology/nvlink: true gpu.pool: high-memory然后在推理 Deployment 里用 nodeSelector 和资源请求锁定apiVersion: apps/v1 kind: Deployment metadata: name: llm-inference-server namespace: ai-production spec: replicas: 2 template: metadata: labels: app: llm-inference warm: false spec: nodeSelector: gpu.pool: high-memory containers: - name: inference image: your-inference-image:latest resources: limits: nvidia.com/gpu: 4 readinessProbe: httpGet: path: /healthz/model-loaded port: 8080 initialDelaySeconds: 10 periodSeconds: 5注意 readinessProbe 的路径是/healthz/model-loaded不是普通的/healthz。这个端点必须等模型权重完全加载进显存后才返回 200否则 HPA 会把进程活着但模型没加载完的 Pod 算进可用容量扩容判断就错了。温备池的维护逻辑核心是维护一组带warm: true标签、模型已加载但不注册路由的 Pod。激活时把标签改成warm: falseService 的 selector 就会把它选进来。下面这段是温备池管理器的关键方法async def activate_warm_pod(self): for pod in self.warm_pods: if pod.model_loaded and not pod.registered: self.core_api.patch_namespaced_pod( namepod.name, namespaceself.namespace, body{ metadata: { labels: { warm: false, ready: true } } } ) pod.registered True return pod.name return None温备池大小建议先设 2观察一周扩容频率再调。每个温备 Pod 独占一张 GPU成本不低A100 按 25 元/小时算2 个温备每月多花约 3.6 万这个账要提前算清楚。4. 压测验证从指标触发到扩容完成的完整链路配置写完不算完得压测验证扩容真的按预期触发。我用 k6 做压测重点观察三个时间点指标超标时刻、HPA 触发时刻、新实例可接流量时刻。先写压测脚本模拟脉冲流量import http from k6/http; import { check, sleep } from k6; export const options { stages: [ { duration: 30s, target: 5 }, { duration: 10s, target: 50 }, { duration: 60s, target: 50 }, { duration: 30s, target: 5 }, ], }; export default function () { const payload JSON.stringify({ model: your-model-id, messages: [{ role: user, content: 解释一下 HPA 的工作原理 }], }); const params { headers: { Content-Type: application/json, Authorization: Bearer ${__ENV.TAOTOKEN_API_KEY}, }, }; const res http.post(https://taotoken.net/api/v1/chat/completions, payload, params); check(res, { status is 200: (r) r.status 200, ttft under 2s: (r) r.timings.duration 2000, }); sleep(1); }跑之前把TAOTOKEN_API_KEY设成你在控制台创建的 Key。压测命令TAOTOKEN_API_KEYsk-xxxx k6 run --vus 50 --duration 2m load-test.js压测过程中另开一个终端盯 HPA 状态kubectl get hpa llm-inference-hpa -n ai-production -w你会看到TARGETS列里队列深度从个位数涨到 10 以上REPLICAS从 2 开始往上跳。同时盯 Pod 状态kubectl get pods -n ai-production -l appllm-inference -w预期结果流量拉升后约 15 到 30 秒HPA 触发扩容如果温备池有货温备 Pod 在 5 到 10 秒内从warmtrue变成可接流量如果没有温备新 Pod 要等 30 秒到 2 分钟加载模型。压测结束后缩容会在 5 分钟稳定窗口后开始每次减 1 个。验证成功的标志有三个一是压测期间 TTFT 没有持续超过 2 秒二是扩容后队列深度回落到 10 以下三是 GPU 利用率在扩容后从 90% 以上降到 70% 左右。如果 TTFT 一直压不下来说明扩容速度跟不上流量爬升速度要么加大温备池要么把 scaleUp 的 periodSeconds 调小。再补一个验证 GPU 池化是否生效的命令看 Pod 是否落在预期的 GPU 节点上kubectl get pods -n ai-production -o wide | grep llm-inference对照节点名和之前打的gpu.pool标签确认没有 Pod 被调度到错误型号的节点上。如果发现 70B 模型的 4 卡 Pod 被拆到两个节点说明拓扑感知调度没生效得检查调度器的find_best_node逻辑。5. 扩容不生效时的常见报错排查扩容配好了但不动是最常见的问题。下面按报错现象逐个排。报错一HPA 显示unknown/10指标读不到。这通常是自定义指标 API 没注册。先查kubectl get apiservices | grep custom.metrics如果没有v1beta2.custom.metrics.k8s.io说明 metrics adapter 没装。装完再查 HPA describekubectl describe hpa llm-inference-hpa -n ai-production看 Events 里有没有failed to get pods metric。如果有检查指标采集器是否真的在暴露inference_queue_depth用kubectl port-forward到采集器 Pod 手动 curl 一下指标端点。报错二local proxy failed或dial tcp连接被拒。这个报错一般出现在网关层转发到 TaoToken API 的时候。先确认 Base URL 写的是https://taotoken.net/api没有多余斜杠也没混入 UTM 参数。然后确认 Key 是从https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建的、状态是启用。如果网关在集群内检查出网策略是否放行了taotoken.net的 443 端口。报错三401 Unauthorized。鉴权失败三种可能Key 拼错、Key 被禁用、请求头格式不对。正确格式是Authorization: Bearer sk-xxxx注意 Bearer 后面一个空格。如果你用的是 Cline 或 Claude Code 这类客户端配置里要写全三件套Base URL 填https://taotoken.net/apiAPI Key 填你的 KeyModel ID 填你要用的模型标识。少任何一个都会 401。报错四error reading choices或返回体解析失败。这通常是响应格式和客户端预期不一致。先确认请求路径是/v1/chat/completions再确认Content-Type: application/json。如果用的是流式检查客户端是否正确处理了data:前缀的 SSE 分片。用 curl 直接打一发最干净curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:your-model-id,messages:[{role:user,content:hi}]}能返回正常 JSON 就说明通道没问题问题在客户端解析。报错五OAuth 相关报错比如OAuth token expired。如果你用的是 Claude Code 这类走 OAuth 的工具报这个说明本地凭证过期了。重新走一遍授权流程或者改用 API Key 方式接入。Claude Code 的接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite里面有 Anthropic 兼容端点的配置说明。报错六Pod 一直 Pending事件显示Insufficient nvidia.com/gpu。这是 GPU 池化没配对。检查节点标签是否和 nodeSelector 匹配kubectl get nodes --show-labels | grep gpu如果节点没有gpu.pool: high-memory标签Pod 就找不到落点。补打标签kubectl label node gpu-node-a100-01 gpu.poolhigh-memory还有一种情况是节点上 GPU 被别的 Pod 占满了kubectl describe node看 Allocated resources 里的nvidia.com/gpu是不是已经到上限。报错七扩容了但 TTFT 没降。这说明新 Pod 没真正分担流量。检查 Service 的 selector 是否匹配新 Pod 的标签尤其是温备 Pod 激活后标签有没有从warm: true改成warm: false。用kubectl get endpoints看后端列表有没有更新。6. 把扩容链路和统一通道串起来整套方案落地后你的推理集群会形成这样一条链路请求经 TaoToken 统一通道进来通道侧按模型维度计数和限流集群侧指标采集器抓队列深度、TTFT、显存利用率增强型 HPA 综合这些指标和流量预测做扩容决策温备池负责秒级激活GPU 拓扑感知调度负责冷备拉起和型号匹配。扩容响应时间从原来的分钟级压到秒级GPU 利用率从长期 90% 以上降到 70% 左右同时避免了碎片化调度。落地顺序建议这样走第一步先给推理服务加自定义指标采集器把队列深度和 TTFT 暴露出来这一步不做后面全是空中楼阁第二步把默认 HPA 换成基于自定义指标的配置观察一周扩容触发是否准确第三步搭温备池先设 2 个温备 Pod跑压测验证激活时间第四步实现 GPU 拓扑感知调度重点验证多卡模型不被拆节点第五步把 TaoToken 统一通道接进网关让多模型接入和配额管理收口同时用通道侧指标交叉验证扩容决策。最后说个容易踩的坑缩容别太激进。我试过把缩容窗口设成 60 秒结果流量稍微抖一下就开始缩缩完又得重新加载模型GPU 反复加载反而更伤。保守点300 秒窗口、每次减 1 个稳得多。温备池的成本账也要定期复盘如果一周下来温备 Pod 激活次数不到 3 次说明池子开大了可以缩到 1 个甚至改成按预测提前拉起。扩容参数没有一劳永逸的值得跟着业务流量曲线持续调。
阅读完成 · 觉得有帮助?