llm-d 推理服务怎样按 GPU 资源拆分请求路由
来源:17golang原创
时间:2026-11-05 13:38:32 138浏览 收藏
llm-d 的“按 GPU 资源拆分请求路由”更准确的理解,不是把请求硬编码到 GPU-0、GPU-1,而是把每个模型服务端点看成一个带有能力和实时状态的候选对象,再由 Router 的 Endpoint Picker(EPP)完成过滤、评分和选择。静态 GPU 能力决定请求能不能去,DCGM 利用率和模型服务指标决定更适合去哪里。
官方地址:https://llm-d.ai/
- 用 InferencePool 组织健康的模型服务端点,不把物理 GPU 编号暴露成业务路由键。
- 把标签和模型兼容性当作硬过滤,把 GPU 利用率、队列、运行请求数和 KV-cache 当作动态评分信号。
- 指标缺失、所有端点过载和异构卡能力不匹配时必须有明确回退,评分不能替代容量边界。
先把 GPU 拆分问题分成三种信号
一个请求进入推理集群时,至少有三类问题需要回答。第一类是“这个端点能不能接”:模型版本、上下文长度、GPU 显存档位、并行方式和角色标签属于相对静态的能力。第二类是“现在是否适合接”:GPU 计算利用率、显存压力或其他硬件指标属于动态状态。第三类是“模型服务是否已经拥塞”:排队请求数、运行请求数、KV-cache 利用率和前缀缓存亲和性属于模型服务器视角的状态。
把三类信号混成一个“GPU 空闲度”容易产生误判。例如 KV-cache 尚未满,不代表 GPU 计算单元没有压力;DCGM 利用率很低,也不代表一个超长上下文请求一定能在该端点获得足够缓存。合理的路由模型应该先用能力做边界,再用状态做偏好。

用 InferencePool 建立可路由的端点集合
llm-d 的模型服务器独立部署,健康后通过 Kubernetes 标签选择加入 InferencePool,EPP 再从池中挑选具体端点。这样做的价值是把“服务发现”和“调度决策”分开:池负责表达哪些模型服务器属于同一组,EPP 负责根据请求和实时数据决定本次落点。
如果集群里同时有大显存整卡、MIG 切片和不同型号加速器,建议先在工作负载标签中表达能力边界,再让池或过滤插件消费这些标签。标签是静态事实,不适合记录每秒变化的 GPU 利用率。
# 下面是标签设计示例,用于表达静态能力,不是完整可直接部署的 InferencePool 清单
metadata:
labels:
llm-d.ai/model-family: qwen
llm-d.ai/accelerator-tier: large-memory
llm-d.ai/serving-role: decode
# 用能力档位而不是 gpu-0 这类物理编号,避免节点重建后路由语义失效
llm-d.ai/capability-context: long-context
实际字段名和标签选择器应以当前 llm-d 版本的资源定义为准。这里的重点不是复制一份 YAML,而是让“端点为什么可用”能够从资源元数据中解释出来。
用过滤器先排除不合适的 GPU 端点
EPP 的调度链路先过滤候选,再评分和选择。过滤适合表达不能违反的约束:模型不兼容、角色不对、静态显存档位不足、GPU 利用率已经超过硬阈值,或者端点不再处于可服务状态。过滤链越清楚,后面的评分越不容易把“根本不能接”的端点排到前面。
GPU 利用率过滤尤其要注意兜底语义。当前项目的 GPU 利用率感知方案以 DCGM Exporter 提供的硬件指标为输入,并通过通用 endpoint attribute filter/scorer 接入调度;硬过滤通常应该排除明显过载的端点,但如果所有候选都超过阈值,不能简单返回空集合,否则一次尖峰就会变成全局拒绝。更稳妥的策略是记录过载状态,再在明确的回退候选中选择最不差的端点,或让上层流控按 TTL 和优先级处理。
# 这是过滤策略的伪配置,展示职责边界;具体插件参数以当前 Router 文档为准
filters:
- type: label-selector-filter
# 先保证模型、角色和静态能力匹配
selector: "llm-d.ai/model-family=qwen,llm-d.ai/serving-role=decode"
- type: gpu-utilization-filter
# 硬阈值用于排除明显过载端点,不等于 GPU 容量承诺
maxPercent: 90
# 全部候选超过阈值时保留回退路径,避免过滤结果为空
fallbackOnEmpty: true
用 DCGM 与服务指标进行动态评分
过滤完成后,评分器才适合回答“优先选择哪一个”。GPU 利用率可以作为“余量越大越优先”的信号;队列深度和运行请求数可以反映模型服务的排队压力;KV-cache 利用率和前缀命中关系则更接近 LLM 的实际复用成本。多个评分器组合时,权重应该对应真实目标,不要把所有指标简单相加后宣称得到了通用最优解。
llm-d 的 endpoint attribute scorer 支持按数值属性归一化。以“越低越好”的利用率为例,评分可以使用固定范围表达 0 到 100% 的已知边界;对队列深度这类开放范围,则更适合按当前候选集合自适应归一化。缺少属性的端点不能被默认为最空闲,应该在数据层记录缺失并根据策略降权或转入回退分支。
# 展示评分思路:先把指标送入属性,再用“越低越好”做归一化
scorers:
- name: gpu-headroom
attributeKey: custom.gpu_utilization_percent
algorithm:
type: linear_lower_is_better
normalization:
fixedRange:
min: 0
max: 100
- name: queue-pressure
attributeKey: custom.queue_depth
algorithm:
# 队列范围随当前候选端点变化,避免写死某个集群的容量
type: linear_lower_is_better
normalization: adaptiveRange
模型服务本身还应暴露队列、运行请求数和 KV-cache 等指标。它们回答的是“模型引擎正在承受什么压力”,不能被 DCGM 的硬件利用率替代。对于前缀复用明显的工作负载,缓存亲和性可能比短时 GPU 利用率更重要,评分顺序和权重应通过 TTFT、TPOT 与缓存命中观测来调整。
处理全满、指标缺失和异构硬件的反例
一套看起来合理的 GPU 路由,通常会在三个反例上暴露问题。
| 反例 | 错误做法 | 更稳妥的边界 |
|---|---|---|
| 所有端点超过利用率阈值 | 过滤后返回空集合,导致请求无解释地失败 | 保留受控回退,交给流控、优先级或排队 TTL 决定是否等待 |
| DCGM 或服务指标暂时缺失 | 把缺失值当成 0,误认为端点空闲 | 标记数据过期,降权或暂不参与首选评分,并保留可观测原因 |
| 异构 GPU 共享一个池 | 只按瞬时利用率排序,忽略显存和并行能力差异 | 先用静态能力过滤,再在同一能力档位内按动态状态评分 |

还有一个容易混淆的边界:GPU 利用率感知路由解决的是“当前端点的硬件压力”,并不自动解决模型需要跨多张 GPU 的张量并行、专家并行或节点级拓扑问题。一个多 GPU 模型服务通常应该作为一个可路由端点暴露,路由器选择的是该服务端点,而不是把一次请求拆成多个独立 GPU 请求。
用可观察性判断路由是否真的改善
发布配置前,先把路由判断拆成可以追踪的证据链:请求进入了哪个 InferencePool,哪些端点因硬过滤被排除,评分使用了哪些属性,最终选择了哪个端点,指标采样是否新鲜。之后再把路由结果和 TTFT、TPOT、排队时长、KV-cache 命中以及 GPU 利用率放在同一时间窗口观察。
如果 GPU 利用率下降了但 TTFT 变差,可能是评分过度偏向硬件余量,破坏了前缀缓存亲和性;如果队列变短但 TPOT 上升,可能是请求被分散到不适合的并行拓扑。调整权重前先确认数据源、采样周期和端点集合没有变化,否则容易把观测问题误判成调度问题。
可以用下面的检查清单做一次设计评审:
- 静态能力是否能解释“为什么这个端点可以接”,并且没有把物理 GPU 编号当作稳定身份?
- 硬过滤是否有全候选超阈值、端点暂时不健康和指标缺失的处理?
- GPU、队列、运行请求数、KV-cache 和缓存亲和性是否被区分,而不是合并成一个无法解释的分数?
- 是否能从 EPP 日志和指标追溯一次请求的候选、评分、选择与结果?
相关问题
llm-d 能不能直接按 GPU 编号路由?
不建议把 GPU 编号作为业务路由键。llm-d 面向的是模型服务端点,GPU 编号会随 Pod、节点和设备编排变化;更稳定的表达是端点标签、模型能力和实时指标。
DCGM 利用率和 KV-cache 利用率有什么区别?
DCGM 利用率描述硬件侧的计算活动,KV-cache 利用率描述模型服务为缓存分配的使用情况。两者观察层次不同,不能互相替代。
评分器是不是越多越好?
不是。评分器越多,权重冲突和解释成本越高。先用少量硬约束和一个明确的主目标建立基线,再根据 TTFT、TPOT、队列和缓存数据增加信号。
llm-d 的 GPU 路由模式可以概括为:能力决定候选边界,硬件与引擎指标决定当前偏好,流控和回退负责承受异常。把这三层职责分开,才能在异构 GPU 集群里得到可解释、可调优的请求落点。
-
241 收藏
-
281 收藏
-
科技周边 · 业界新闻 | 9分钟前 | 云原生 · kubernetes · 网络安全 · eBPF 网络策略 Cilium CiliumNetworkPolicy CiliumClusterwideNetworkPolicy toServices 节点策略196 收藏
-
297 收藏
-
213 收藏
-
280 收藏
-
426 收藏
-
268 收藏
-
170 收藏
-
150 收藏
-
448 收藏
-
490 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习