使用 eBPF 实现 LLM 推理服务的全栈可观测性


                                                                                                                                                <blockquote> 

文章内容来自 DeepFlow 在2025年3月15日 KCD 大会上的演讲内容,分享 DeepFlow 在大模型推理服务可观测性方面的实践。

DeepFlow 基于 eBPF 技术,覆盖不同模型、推理引擎与硬件环境,实现 LLM 推理服务的全栈可观测性。今天的分享我将从四个方面展开:首先是自建 LLM 推理服务面临的挑战;其次是如何构建大模型分布式推理服务的可观测性;然后介绍如何利用eBPF技术实现全栈观测;最后分享DeepFlow在这一领域的实践与应用。

一、自建 LLM 推理服务的挑战

首先谈谈自建大模型推理服务的挑战。这个话题在两个月前可能还不算突出,因为当时自建推理服务的情况并不多见。但随着DeepSeek的走红,无论是互联网公司、行业客户还是政企单位,都开始积极搭建自己的模型,这也带动了国产GPU的快速落地。热潮之下,问题也随之浮现。

以往搭建一套推理引擎或服务尚需一定的技术积累,而DeepSeek的出现加速了这一过程,同时也带来了两方面的问题。左侧观点指出当前硬件市场“水很深”,即便是同一种硬件卡(如910B),也存在多种细分型号,其中信息并不完全透明。

如何保障自建LLM推理服务的用户体验

右侧则反映了另一个现实:尽管DeepSeek及相关工具是开源的,但真正搭建起可用的推理引擎,仍然依赖“模型搬运工”和专家支持,技术门槛依然显著。以往大家在搭建私有化推理服务时,可能更倾向于百亿参数规模、单卡即可支持的模型。而如今DeepSeek激发了大家尝试千亿参数、完整版模型(如671B)的热情。这意味着需要跨越多机、多节点、多卡进行分布式推理协同,才能保证千亿参数模型的顺畅运行,达到人均阅读文字所对应的每秒20个Token以上的吞吐率,并支撑企业内至少几十个并发请求——这仍然是一个对专业技术要求很高的领域。

在国内的实践中,这一挑战尤为突出。首先是硬件卡的稀缺性问题。过去搭建百亿参数推理引擎时,或许还能采用英伟达的H20、L20等相对低端的卡。如今要部署千亿参数模型,却面临高端卡禁运的局面,不得不转向国产卡。而国产卡在规格、性能、实际表现以及相应的开发生态——包括性能剖析、运维调优等工具链支持上仍存在不少短板。

对于大型企业而言,采购时往往面临混合选用不同品牌、不同型号异构卡的复杂情况。如何进行选型、配比,以及后续的参数调优,都成了亟待解决的问题。

那么为何参数调优如此关键?微软亚研院(MSRA)曾对七百多个GPU低效使用案例进行分析,发现低效情况大致可归纳为三类,各占约四分之一。

同样的训练/推理代码在不同硬件下的性能表现

第一类与GPU内核计算有关。例如,在测试集群中使用较小的batch size进行训练或推理,以适应测试环境;但到了生产集群,若未根据不同的硬件条件调整此参数,就可能导致GPU利用率低下。这种情况在英伟达生态中已存在,而在国内行业用户面对的多样硬件环境下,问题可能更加复杂——在A硬件上有效的配置,在B硬件上可能需要完全不同。这类因代码配置导致的问题,约占低效案例的20%以上。

第二类问题与显存操作相关。例如,代码中将数据从主机内存复制到HBM显存,或在不同卡之间进行数据拷贝时,可能因未妥善处理阻塞操作而造成不必要的延迟。

近期DeepSeek在开源周报中发布的性能剖析数据也致力于优化此类通信与计算的重叠执行,以尽可能提升GPU利用率。这同样是导致GPU低效运转的原因之一。

第三类问题则涉及文件读写,这在训练任务中更为常见。例如,将检查点写入本地磁盘或分布式文件系统时,若I/O性能不足,会对整个训练进程造成瓶颈。

今天主要探讨推理服务。推理任务本身最初或许不涉及此类问题,但随着DeepSeek的出现,推理过程中也开始产生读写磁盘或对象存储的需求。由此导致的低效用例也占了10%以上。

千亿参数LLM推理服务、AI智能体点复杂性

回到千亿参数模型的推理场景。如图所示,左侧示意在千亿参数规模下,我们往往不得不采用分布式推理服务。例如,基于ACK的DeepSeek“满血版”分布式推理实践中,就提及了使用vLLM和Ray等工具构建分布式推理服务,以实现多节点、多卡上千亿参数模型的有效推理。

这还只是相对简单的分布式形态,仅涉及若干进程。右侧则展示了另一个日益常见的场景:推理服务需要接入当前热门的AI智能体体系。Chatbot只是一种简单形态,若考虑完整的AI智能体应用,它还需要与模型、工具以及记忆系统等进行交互。这实际上构成了一个相当复杂的分布式系统。

总的来说,以上所述正是当前推理服务面临的多重挑战。

二、如何建设推理服务的可观测性

接下来我们分享如何构建推理服务的可观测性。谈到可观测性,大家通常都会提及经典的三大支柱:指标、追踪与日志。理论上,将这些数据收集齐全便足以支撑观测需求。

云原生环境下LLM推理服务的可观测性

而OTel在2024年(其实从2023年已开始)将性能剖析数据提升为至关重要的第四大支柱,这对应我们前面提到的、由MSRA分析的代码导致的GPU低效使用问题,是一种非常重要的能力。集齐这些能力似乎就够了?实际上,LLM推理引擎或推理服务更贴近基础设施层,这与通用的分布式应用系统有所不同。当前许多实践也建议在 K8s 容器环境中搭建推理服务,这使得可观测性面临一些差异。

例如在指标层面,vLLM与Ray等进程之间在推理时,Token是以流式方式输出的。我们观测首次Token延迟或每个输出Token的时间时,不能只关注单一节点,而需要审视全链路的每一个环节,比如K8s中每一张网卡的时迟消耗情况。

在追踪方面,对于K8s基础设施,我们除了要看到每个环节的时延,还需关注基础设施服务(如最基础的DNS,或数据库、向量数据库等)在整个调用链中的状态与性能。

至于性能剖析,除了CPU剖析,更需要与GPU上下文结合;除了主内存的剖析,还需要具备高带宽内存(即显存)的剖析能力。这能帮助我们快速识别推理引擎运行时的OOM(Out of Memory)根源。事实上,在vLLM的GitHub Issue中,时常出现升级新版本或使用某型号卡时引发的显存OOM问题,这也是一个新的挑战。

下面我们将分享,可以运用哪些通用或传统手段来解决这些挑战和问题,构建可观测性。

  • 推理服务指标数据

推理服务Infra指标:Prometheus+NVIDIA DCGM Exporter

我们首先来看指标。指标通常分为基础设施指标和业务指标。基础设施指标主要指GPU卡的用量、功耗等,这需要由硬件主动暴露。例如英伟达通过DCGM Exporter来暴露整张卡的指标。但这里存在一个局限:如果GPU被虚拟化,每个虚拟卡的详细指标受限于硬件本身的暴露能力,很可能无法完整获取。

推理服务业务指标:Prometheus+L7 AI Gateway Metrics

接着看业务指标。如果依赖推理引擎自身提供,其完备性可能不足。当前开源的推理引擎众多,如SGLang、TensorRT-LLM、vLLM 等,它们未必能为各种模型提供丰富的业务指标,例如:Token生成速率、首次Token延迟、每个输出Token的时间等。

一种常见的变通方案是通过网络网关进行观测。目前许多LLM网关都具备AI Gateway能力,可以在网关侧暴露业务指标。但无论哪种方法都会存在问题:若由业务自身暴露,则需要插入Prometheus SDK进行埋点;若仅在网关处暴露,则观测视角仅限于网关这一个点。在云原生环境下,要洞察K8s节点、网卡等不同环节的性能表现,仍然存在挑战。

  • 调用连追踪

调用链追踪:分布式推理服务 Instrumentation

接下来看追踪。由于推理服务及其前置的智能体或接入服务构成了一个复杂的分布式应用,构建链路追踪能力就显得非常关键。目前已有不少开源工具,例如基于OpenTelemetry的OpenTracing,以及OpenLIT等,它们支持的能力相近,主要通过Python或JavaScript/TypeScript的插桩库来实现分布式追踪。

但现有方案也存在一些不足:其一,通常只能关注单个进程内部的耗时消耗,难以扩展到整个K8s链路上,呈现从基础设施到应用的全路径时延。其二,对多种编程语言的支持仍在逐步完善中。

  • 性能剖析

性能剖析:GPU Profiling、HBM Porfiling

接下来我们看看性能剖析方面现有的工具与能力。如图所示,左侧是NVIDIA Nsight提供的性能剖析能力。这是一种较为底层的工具,主要面向系统工程师或GPU工程师进行性能调优,可以深入观察GPU内部处理单元或显存的利用率等情况。

但对于上层应用(如推理服务或训练进程)的开发者而言,这类工具缺少CPU上下文信息,存在一定认知隔阂。以往,推理或训练任务可能只由少数专业工程师负责,他们能够解读左侧的剖析数据。然而当下,越来越多的工程师需要参与推理服务的开发和运维,他们更熟悉且需要的是贴近CPU上下文、能够展示Python函数调用栈的剖析能力——这正是右侧PyTorch Profiler所提供的。右下角展示的函数调用栈信息,对于在GPU之上进行应用开发的工程师来说更加直观友好。

然而在Python中获取此类调用栈信息,通常需要进行手工打造的精细插桩。例如在训练过程中,可能需要设置等待轮次、预热轮次、激活轮次等。由于性能开销较大,这种插桩需要精巧的设计:一般在测试阶段先运行一次以获取剖析数据,据此进行优化,而后在正式训练或推理前移除这部分代码。

综上所述,现有手段已能覆盖指标、追踪、剖析和日志这四大支柱,虽然已有不少工具,但在两种场景下仍显不足:第一,随着更多应用工程师需要面对推理服务,工具需要变得更简单易用;第二,在云原生环境中,我们不能只观测单点,否则在排查问题时可能忽略某些由基础设施,或者特定型号GPU卡导致的影响。

三、基于 eBPF 的全栈可观测性

为什么实用eBPF:零侵扰、全栈

我们首先通过这张图快速说明采用eBPF技术的优势。左侧示意图见于eBPF.io官网,其核心优势可概括为“零代码修改”与“全栈观测”。即无需改动应用代码或重启进程,即可获取可观测性数据;并且不仅能获得进程内部的数据,还能覆盖Linux内核乃至整个软件栈的观测信息。例如,可以将一次推理请求从应用层到系统调用、再到网卡驱动的完整路径串联起来。

右侧是我补充的一点:eBPF不仅是Linux内核的技术,其在用户态同样具备强大的uprobe能力。尽管常有人说uprobe的开销会比内核态的kprobe更大,但这里有一个关键点:在计算密集型场景中,许多关键操作(如GPU内核函数调用,或基于InfiniBand等高速网络的通信调用)本身开销就已非常大。因其自身开销巨大,在其上附加uprobe所带来的额外资源消耗或时间代价往往微不足道。根据我们的实际测算,额外损耗仅在个位数百分比(例如1%到5%)之间。因此,在右侧所示的这类计算场景中,uprobe是完全可用的,其开销有时甚至低于许多传统插桩方式引入的性能损耗。

  • DeepFlow 全栈指标采集能力

采用eBPF技术后,我们能在指标、追踪、剖析等方面获得怎样的实际收益呢?首先从指标角度来看,在云原生环境下,我们获得了非常全面的全栈指标采集能力。

Metrics:云原生环境下需要全栈性能指标

以一个典型场景为例:假设一个Nginx Gateway将负载分发到后端的Serving Pod。如果出现TTFT或TPOT指标的异常波动,而我们无法确定问题是否出在模型服务侧,那么中间K8s基础设施层可能存在的问题点就非常多了。若需要定位一个每小时仅偶发一次的抖动,传统上可能需要在多处抓取tcpdump或分析Nginx访问日志,排查效率很低。

Metrics:实用eBPF采集LLM推理服务的全栈指标性能

但如果利用eBPF采集所有相关网卡的流量,并对其时延进行计算,我们就能得到一张全栈路径的指标视图。以时延为例,从客户端进程、eBPF捕获的系统调用、客户端Pod的网卡、到K8s节点的网卡,如果节点还部署在KVM宿主机上,甚至可以延伸到宿主机节点的网卡——整条路径上每一段的时延消耗都能清晰地展现出来。这样我们就能直接判断问题是否源于基础设施层,避免了在云原生环境中搭建LLM服务平台时常见的定界不清问题。

Metrics:实用eBPF的主要挑战,Steaming API

因此,第一个显著的收益是能够充分释放全栈观测能力,使推理引擎在云原生环境中的落地更顺畅。当面临时延异常时,也能更快地进行定界。不过这里也存在挑战:对于HTTP协议,计算请求与响应的时间差即可;但在推理场景下,要计算TTFT或TPOT等指标,则需要理解流式的推理协议,这增加了工程实现的复杂度。这是第一个挑战。

Metrics:实用eBPF的主要挑战,新的协议

第二个挑战,是近期备受关注的Model Context Protocol(MCP)。作为一种新的协议规范,它与HTTP有所不同,我们无法直接沿用HTTP的逻辑从通信报文中解析指标。因此,我们需要理解并解析这一新协议,从而在智能体侧——即推理引擎的外围,也能获得良好的指标采集能力。这是指标层面面临的挑战。

  • DeepFlow 全栈全链路追踪能力

Tracing:实用eBPF实现Python、Golang推理引擎的追踪

关于追踪能力,这里可以简要带过。熟悉DeepFlow的朋友可能了解,我们利用eBPF实现了一种创新性的AutoTracing能力,能够覆盖基础设施网关、K8s网卡、CoreDNS乃至数据库等全链路组件,并能较好地识别Python等非Java语言。

这里还有一个新的关注点。DeepSeek推出后引入了一项重要创新:多头注意力机制 MLA。MLA 的创新使得KV Cache的尺寸大幅减小,据说DeepSeek可能是全球首家在推理服务中使用磁盘Cache的厂商。可以预见,未来为了降低部署成本,自建推理服务也会越来越多地采用磁盘或对象存储的KV Cache。

Tracing:实用eBPF实现Disk/OSS KV Cache IO 的追踪

那么,如何在追踪链路中展示相关的IO调用呢?我们在右上角的Span示例中已经做了一些工作。右下角则展示了如何在DeepFlow Agent中配置,使其在采集一次调用时,能关联采集到相应的IO事件。

  • DeepFlow 全栈函数级性能剖析能力

Profiling:使用eBPF获取Python & C++的函数调用栈

Profiling:使用eBPF获取Python & C++的函数调用栈

性能剖析方面的情况较为复杂,我简要提及几点。例如,我们如何实现Python与C++调用栈的合并,使得在观察GPU Profiling或HBM Profiling时能看到完整的调用栈?由于整个函数栈比较复杂,像vLLM和PyTorch的上层是Python函数(基于Python运行时),底层则是C++库,将它们连接起来是一个技术挑战。

Profiling:计算On-GPU Profiling

另外,如前所述,GPU的很多计算是异步的。我们如何准确计算程序在GPU上的耗时,而不仅仅是CPU上的耗时,这需要我们分析异步执行流程,将同步与异步调用结合起来,从而计算出真实的GPU耗时。

四、DeepFlow 用户实践

DeepFlow可观测性平台

上述介绍的是DeepFlow使用的一些技术手段,来达到的新能力。下面简要分享两个用户实践,基于eBPF与WASM,DeepFlow构建的能够零侵扰获取性能剖析与分布式追踪数据的可观测性平台。

DeepFlow 智能体:产品架构

首先是我们自身的实践。我们在内部部署了基于推理服务构建的AI智能体,用于自动解读可观测性数据,这本身也是对自身产品的一次验证。该智能体拥有多个应用场景,例如分钟级的故障诊断与巡检、一句话问数,智能体需要频繁调用大模型的推理能力,同时还需调用各类工具以获取观测数据,并通过Ray系统来存取记忆信息。

DeepFlow智能体:使用Profiling剖析vLLM+Ray推理服务

DeepFlow智能体:使用Profiling剖析vLLM+Ray推理服务

DeepFlow智能体:使用Profiling剖析HBM申请和使用

整个架构包含感知、推理、执行等层次,是一个运行于K8s之上的复杂推理服务。我们利用eBPF能力,实现了对vLLM服务的GPU性能剖析,以及对其他服务CPU与GPU的混合剖析。同时,也能清晰呈现显存申请与使用的函数调用栈热点。所有这些能力的目标,并非为了直接修改vLLM等引擎,而是为了让我们能在不同的硬件卡上更好地进行参数调优,使服务配置能最佳地适配所面对的各种型号的硬件。

中国移动:深度解析DeepFlow如何采集大模型服务的业务指标

另一个案例来自中国移动。他们基于DeepFlow的WASM插件能力,成功将其推理服务的多项业务指标以零侵扰的方式采集出来,并在微服务云原生环境下实现了全链路指标汇聚。无论是TTFT还是TPOT,都能适配其自有的推理协议,无需业务改造即可实现全栈业务指标的采集与分析。

以上就是我今天的所有分享,谢谢。

                                                                                </div>



Source link

未经允许不得转载:紫竹林-程序员中文网 » 使用 eBPF 实现 LLM 推理服务的全栈可观测性

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
关于我们 免责申明 意见反馈 隐私政策
程序员中文网:公益在线网站,帮助学习者快速成长!
关注微信 技术交流
推荐文章
每天精选资源文章推送
推荐文章
随时随地碎片化学习
推荐文章
发现有趣的