-
Agent可观测的必要性 在传统软件系统中,可观测性(Observability)解决的是系统是否正常运行的问题。但在 Agent 系统中,这个概念则是:系统不仅要运行地正确(系统执行正确),还要正确地运行(语义执行正确)。引入大语言模型后,Agent的执行过程从确定性流程转变为基于推理的动态决策,导致系统行为对用户而言变得不可预测且难以理解。当结果异常时,既无法复现问题,也难以判断是模型决策、工具调用还是上下文理解出现偏差,而传统监控体系又难以感知这类语义层错误。过程不可见、问题难定位,使系统在实际使用中缺乏可控性和可维护性,因此必须构建面向Agent的可观测体系,对其执行链路和决策过程进行记录与还原,为问题定位和系统优化提供基础支撑。 Agent可观测应具备的四个基础能力 1、指标追踪能力:分布式架构下,底层模型的计算开销分散于各业务节点。研发与运维团队经常需要评估智能体或工作流的资源投入产出比,并据此进行容量规划和运行成本管控。缺乏全局视图会导致计算资源消耗不明,系统规模化部署后成本处于失控状态。因此,可观测体系必须具备智能体概览分析能力,支持采集并聚合词元消耗总量、模型请求频次、端到端延迟、请求成功率等核心业务指标。2、会话回溯能力:单次任务调度被拆分为多个异步执行的推理与调用节点,导致多轮交互逻辑在原生运行环境中处于离散状态。故障排查时将碎片化的底层调用日志还原为完整的自然语言交互过程困难重重,难以复现引发错误的初始上下文条件。因此,可观测体系需具备跨度关联的会话分析能力,支持通过会话标识检索并提取对应的完整调用拓扑,按时间序列完整重构对话过程。3、链路拓扑能力:Agent任务抛出异常、产生逻辑死循环或遭遇外部响应延迟时,由于缺乏各执行节点的运行状态快照,工程师无法迅速隔离并界定系统故障域。 因此,可观测体系需具备深度的调用链分析能力,支持基于追踪标识精准定位目标会话,并允许按应用类别、组件名称及节点层级进行过滤筛选。此外,需支持提取单一跨度的全量元数据,包括执行状态、精确耗时、输入输出报文、系统标注及底层运行时日志,实现运行现场的精准还原。4、操作留痕:智能体具备自主调用宿主机命令行或读写系统文件等高危工具的权限,系统极易遭受指令注入攻击,引发未授权的数据越权访问。因此,可观测体系需建立指令级别的留痕机制。针对系统预定义的高危工具集,强制记录发起调用的会话标识、原始提示词意图、目标参数及鉴权结果,确保每一次敏感资源交互均具备不可篡改的日志证据链。 AgentArts Ops构建标准化可观测方案 1、标准支持:原生兼容 OpenTelemetry 规范,用户只需授权相关服务开通和接入,就能在底层完成 Agent 与 OfficeClaw 运行环境下的日志流、性能指标与分布式链路追踪数据的提取。对于基于该标准协议构建的Agent 应用,系统直接支持其链路追踪数据的全量接入与结构化解析,提取离散的日志流、性能指标与调用拓扑数据。2、全链路可观测:在获取上述底层异构数据后,系统的聚合计算层随即对跨节点数据进行时序对齐与关联绑定,自统计资源开销、全局并发与交互会话维度的可视化监测视图。3、细粒度追踪:围绕“成本可控、过程可还原、问题可定位、风险可追责”的核心诉求,实现:(1)全局指标追踪:清晰掌握模型调用带来的资源消耗与系统负载情况;(2) 会话级回溯:将分散的多轮推理过程还原为完整执行路径;(3) 调用链分析:精确定位到决策或工具调用出现异常的环节;(4) 对高风险操作的留痕与审计:确保所有关键行为都有据可查。以上方案通过AgentArts Ops 的四大能力实现:1、业务指标观测:从全局视角实时刻画系统运行状态,围绕 tokens 消耗、模型调用次数与耗时、请求成功率等核心指标,帮助用户快速了解系统负载与性能瓶颈。 2、运营指标观测:面向应用与业务层的运行分析能力,支持从智能体规模到增长趋势的整体把控,并通过活跃应用数及多维 Top 排行,快速识别高价值或高消耗对象,辅助运营决策与资源分配优化。3、会话观测:以单次用户交互为核心,还原完整执行过程。系统按会话维度展示ID、总耗时、词元使用(输入/输出拆分)、调用链数量等关键信息,并支持逐条展开每一次调用链中的多轮对话内容,使复杂任务的执行路径清晰可见。4、调用链观测:深入到执行细节层,对每一次任务的调用链进行结构化展示。系统逐节点呈现各环节的执行状态、耗时及输入输出信息,并标记异常与错误日志。▍实践案例一:网络异常的级联故障发现一、问题:工作流引擎在执行特定智能体任务时未返回预期生成结果,前端网关接收到请求超时或非标准状态码。 导致业务调用方无法界定故障域到底是处于提示词超长、模型服务端限流、还是内部网络侧基础设施异常。二、影响:故障定界的模糊直接阻断了服务自愈与自动化重试策略的执行。三、诊断方式:1. 拓扑状态断言与故障域隔离运维人员通过会话标识检索分布式链。可观测系统根据各节点的执行状态码,在拓扑链路中对产生异常的跨度进行显式标记。系统将故障域直接锁定在大模型执行节点。如下图所示,执行失败的调用链中标记出错节点,其中结束节点中第一行日志标记了结束节点遇到的错误。日志如下:2. 运行现场报文快照提取针对被标记的异常跨度,系统提取执行瞬间挂载的元数据。日志数据显示,异常发生前,系统已成功完成运行参数的组装,此步骤排除了业务代码传参逻辑缺陷的可能。2026/04/23 22:30:16.245 GMT+08:00 model call request data: {"model": "deepseek-v3.1-terminals", "stream": false, "temperature": 0.5, "max_tokens": 4096, "messages": [{"role":"system","content":"..."}]}3. 根因确立沿着时间序列解析该跨度的标准错误输出流,日志明确指出请求目标主机时发生域名解析失败,确立根因为底层网络环境配置问题,而非算法模型侧故障。2026/04/23 22:30:26.159 GMT+08:00 Cannot connect to host api.modelarts-maas.com:443 ssl:False [Name or service not known]▍实践案例二:鉴权凭证缺失引发的模型节点阻断一、问题:工作流引擎在流转至大模型推理节点时,触发 HTTP 400 请求参数错误告警,任务实例强制终止。二、影响:业务端完全无法获取模型生成结果。三、诊断方式:1. 运行现场报文快照提取运维人员通过异常追踪标识下钻至目标跨度。元数据快照显示,业务载荷层面的模型超参装配完整,排除了模型提示词构造缺陷的排查方向。2026/04/21 09:59:31.033 GMT+08:00 model call request data: {"model": "deepseek-v3.1-terminus", "stream": false, "temperature": 0.5, "top_p": 0.5, "max_tokens": 4096, "frequency_penalty": 0.0, "messages": [{"role": "system", "content": "..."}]} 2. 异常传播链与合规缺陷分析系统按时序反序列化执行日志,清晰呈现了由于代码合规缺陷引发的安全拦截闭环:凭证丢失:组件在发起请求前置阶段,没有写入Authorization字段内容导致模型鉴权失败。2026/04/21 09:59:31.033 GMT+08:00 Node execution error | flow_id: 81c2bcf5-63f7-4688-827f-e42a5446d771 | node type: juwen.LLMComponent | node name: 大模型 | origin error code: 101563 | origin error message: Get model streaming output error, msg=Model request error: Failed to get the authorization header框架级联问题:未受控的鉴权异常直接击穿组件层,引发节点执行失败。同时,极端状态下的线程崩溃再次导致系统内置的遥测探针在剥离追踪上下文时发生执行器报错。2026/04/21 09:59:31.033 GMT+08:00 OTEL_PROBE | detach context error3、根因确立系统组件代码中存在违规的鉴权旁路判断逻辑,导致向下游云端大模型发起网络调用时,HTTP 请求头中缺失必需的凭证字段。上述两起排障实践中的域名解析失败与鉴权凭证丢失,是常见的基础网络配置错误,定位并不复杂;但在引入大模型并采用分布式Agent架构后,简单的底层故障可能会被放大,随着多轮推理和跨服务调用被传递到不同的环节,问题与根因往往相隔很远、时间无法对应,导致定位成本迅速失控。所以可观测体系能够串联起不同服务和层级的执行信息,还原出一条完整的执行路径,让工程师可以从结果回溯,精准定位到问题。让Agent系统真正从“出了问题靠猜”走向“出了问题能查清”,支撑稳定的生产运行。 AgentOps 自驱动闭环架构演进路线 AgentOps的目标不只是“能发现问题”,而是要构建一个由数据驱动的闭环体系,让系统具备自我发现、自我诊断以及自我修正的能力。而“可观测”是这一切的前提,既要看得见系统在做什么,也要能评估行为是否合理。AgentArts 已经在底层完成了可观测探针与多维评估引擎的标准化建设,能够在不侵入业务逻辑的前提下,持续采集运行数据并建立全局的性能基线与异常链路视图。建议在系统投产初期就引入可观测能力,形成统一的数据底座,后续无论是自动化诊断还是策略级优化,都可以直接基于已有数据展开分析,真正支撑Agent系统向稳定可控、持续演进的方向发展。 欢迎体验AgentArts可观测和可评估能力 关注魔方公众号,获取更多前沿资讯添加社区小助手k8s2222,进入Kthena技术交流群
-
Karmada 非常高兴地宣布, Wellhub正式加入 Karmada 用户组,成为社区的重要成员。作为云原生计算基金会(CNCF)旗下项目,Karmada 致力于为用户提供强大的多集群管理和调度能力,帮助企业在复杂的分布式环境中实现高效的应用部署和管理。Wellhub的加入将进一步加强 Karmada 社区,为项目的持续创新带来新的活力,标志着我们社区发展和 Karmada 在多样化生产环境中采用的又一个重要里程碑。▍Wellhub,驱动全球企业健康转型的数字引擎Wellhub (https://wellhub.com/en-us/)秉持一大使命:助力每家企业转型为健康型企业,让员工每日关注自身身心健康状态。为此,平台推出高性价比、一站式综合服务方案,全面守护员工的身体、心理、营养与情绪健康。依托 Wellhub,员工无论居家还是在职场,都能主动建立并长期坚持健康的日常生活作息。目前,全球 11 个国家超 19000 家企业已选用 Wellhub,为数百万员工提供行业顶尖的企业健康福利项目。该项目经实践验证,能大幅提升员工参与度与投入度。Wellhub 可使参与健康管理的员工数量实现翻倍增长。员工的广泛参与,能让企业人员流失率降低 40%,同时为企业节省最高 35% 的医疗相关开支。 ▍技术落地:通过Karmada实现多集群资源统一管理随着业务快速扩张,Wellhub 构建了大规模的多集群 Kubernetes 环境,需要高效管理分布在不同地域和云上的服务网格配置。在生产环境中,Wellhub 采用 Karmada 作为多集群编排平台,核心使用场景是大规模分发 Istio 资源。通过 Karmada 的 Propagation 策略,Wellhub 构建多集群架构将 VirtualService、DestinationRule 和 ServiceEntry 等 Istio 关键资源一键分发到整个集群舰队(fleet),实现服务路由、流量治理和外部服务注册的统一管理。作为其云原生基础设施的重要组成部分,该实践不仅提升了平台的可扩展性,也降低了多集群管理的运维成本,帮助工程团队将更多精力投入到业务创新和健康体验优化上。与此同时,Wellhub 的案例为其他大规模采用 Istio + Kubernetes 的企业提供了宝贵参考,尤其适合拥有全球分布式集群、需要统一治理服务网格配置的组织。 ▍欢迎加入Karmada用户组Karmada 用户组是一个由在其环境中成功采用 Karmada 的组织和用户组成的社区。加入用户组可与同行深度交流协作并共享最佳实践,优先获悉关键版本更新与安全通知。此外,成员还将受邀参与 KubeCon 等官方活动,享有社区职位发布、拓展潜在商业合作等专属权益:🔖 Karmada adopter-group:cid:link_1您可以在 GitHub 社区仓库中了解更多关于 Karmada 用户组的信息,截至目前,Karmada 用户组已吸纳来自全球的 40+ 家企业和组织。更多使用场景及案例研究请查阅:https://karmada.io/adopters您是否在生产环境中使用 Karmada ?欢迎加入Karmada用户组!访问下方 Karmada 用户组申请链接 ,提交 issue 申请,即可接收申请进度:Karmada 用户组申请表单: cid:link_0 扫码加入用户组如需了解更多关于 Karmada Adopter Group 的信息,请联系:Maintainer Mailing List:cncf-karmada-maintainers@lists.cncf.io 关注魔方公众号,获取更多前沿资讯添加社区小助手k8s2222,进入技术交流群
-
欢迎阅读【LLM推理】专栏系列文章,在首个系列,我们将带来大模型智能推理方向开源项目Kthena技术解析: ★【第一期】《Kthena 核心原语:ModelServing CRD 如何定义分布式推理的“新标准”?》★【第二期】《Kthena Router:插件架构解析及Benchmark测试》(本文)★【第三期】《Kthena AutoScaling:深度解析 Kthena 如何通过“语义感知弹性”重塑 AI 推理成本》★ 项目地址:cid:link_0/ 本文深入分析 Kthena Router 中 ScorePlugin(评分插件) 模块的系统设计与实现。该模块利用可配置、可插拔的架构,实现了推理请求的多维度评分和智能路由。我们将详细探讨目前已实现的六种 ScorePlugin,并构建一个基于 DeepSeek-R1-Distill-Qwen-7B 模型的标准化基准测试环境,评估不同调度策略在长、短系统提示词(System Prompt)场景下的性能表现。实验结果表明,在长系统提示词场景下,“KVCacheAware 插件 + Least Request 插件”的组合实现了 2.73 倍的吞吐量提升,并将 TTFT(首字延迟)降低了 73.5%。这显著优化了整体推理服务性能,验证了缓存感知调度对于长文本推理的核心价值。1. 背 景 随着大语言模型(LLM)推理需求的爆炸式增长,如何高效利用 GPU 资源并降低延迟成为核心挑战。传统的负载均衡器(如简单轮询或随机分发)在处理 LLM 推理请求时显得捉襟见肘,因为它们无法感知后端的实时负载、KV Cache 状态以及预填充(Prefill)与解码(Decode)分离的复杂需求。Kthena 作为一个云原生、高性能的 LLM 推理路由与调度系统,通过其 ScorePlugin 机制提供了灵活的流量管理能力。2. ScorePlugin 架构设计 ScorePlugin 采用插件化设计,允许用户根据业务场景自由组合不同的评分逻辑。type ScorePlugin interface { Name() string Score(ctx *Context, pods []*datastore.PodInfo) map[*datastore.PodInfo]int }每个插件会根据特定的指标为候选后端(Pod)打分,Router 最终汇总这些分数并选择得分最高的节点转发请求。目前 Kthena 实现了以下六种核心插件:① GPU Cache Usage Plugin: 实时监控 Pod 的 GPU 显存缓存使用率,优先调度到使用率较低的节点以降低显存溢出风险。② Least Request Plugin:通过优先将任务调度到已缓存所需数据的节点,显著降低数据传输开销并缩短大模型等任务的启动延迟。③ Least Latency Plugin: 根据监控到的首字延迟(TTFT)和单字生成延迟(TPOT)指标进行打分,优先选择性能表现更优的 Pod。④ KVCacheAware Plugin:核心插件。 它通过计算请求的提示词(Prompt)与后端 Pod 中已缓存内容的匹配度进行评分。匹配度越高,得分越高。这能极大提高 KV Cache 复用率,减少 Prefill 阶段的计算量。⑤ Prefix Cache Plugin: 利用字节级前缀匹配算法和 LRU 淘汰机制,优先选择具有最长前缀匹配记录的 Pod 以提升缓存效率。⑥ Random Plugin: 在候选节点中随机选择,适用于对调度要求不高的简单场景。3. ScorePlugin 插件实现细节 3.1 GPU Cache Usage 插件(GPU 缓存使用率插件)一种基于 GPU 显存缓存利用率 的资源感知型调度策略。算法原理:实时监控每个 Pod 的 GPU 缓存使用率 (GPUCacheUsage)。评分函数:Score = (1.0 - GPUCacheUsage) x 100优先选择 GPU 缓存占用较低 的 Pod,从而降低显存溢出(OOM)的风险。适用场景: 显存资源受限或显存压力较大的环境。3.2 Least Request 插件(最少请求插件)一种基于 活动请求队列长度 的负载均衡策略。▍算法原理:监控指标:正在运行的请求数:RequestRunningNum等待队列长度:RequestWaitingNum基础负载计算:base = RequestRunningNum + 100 x RequestWaitingNum归一化评分:score = ((maxScore - baseScores[info]) / maxScore) x 100▍关键设计细节:将等待队列的权重因子设置为 100,旨在严厉惩罚已有请求堆积的 Pod。实现 动态负载感知 的均衡分布。3.3 Least Latency 插件(最低延迟插件)一种以 推理延迟指标 为驱动的性能导向型调度策略。▍算法原理:监控指标:TTFT (Time To First Token,首字延迟)TPOT (Time Per Output Token,单位输出 Token 延迟)归一化处理: ScoreTTFT = (MaxTTFT - CurrentTTFT)/ (TTFT - MinTTFT)x 100 ScoreTPOT = (MaxTPOT - CurrentTPOT)/(MaxTPOT - MinTPOT)x 100最终加权评分: Score = α x ScoreTTFT + (1 - α) x ScoreTPOT▍配置参数:TTFTTPOTWeightFactor:0.5 # TTFT 权重因子 α3.4 KVCacheAware 插件(KV 缓存感知插件)一种利用 KV 缓存命中率 的高级 缓存感知调度策略。技术亮点:Token 级语义匹配:使用特定模型的 Tokenizer 进行精确分词。分布式缓存协同:通过 Redis 实现跨 Pod 的状态同步。优化连续块匹配算法:最大限度提高缓存命中率。算法工作流:① 分词阶段 (Tokenization)输入 → 模型特定 Tokenizer → Token 序列 [t₁, t₂, ..., tₙ]② 分块切割 (Block Segmentation)Token 序列 → 固定大小的数据块 [B₁, B₂, ..., Bₘ] 数据块大小:128 tokens(可配置)③ 哈希生成 (Hash Generation)对每个 Bᵢ 计算:Hash(Bᵢ) = SHA256(Bᵢ) → hᵢ④ 分布式缓存查询Redis 管道查询: 针对每个 hᵢ → 获取 {Pod₁: 时间戳₁, Pod₂: 时间戳₂, ...}⑤ 连续匹配评分Score = (连续匹配的数据块数量 / 总块数) × 100配置示例:blockSizeToHash:128 # Token 块大小 maxBlocksToMatch:128 # 最大处理块数Redis 键值结构:Key Pattern: "matrix:kv:block:{model}@{hash}" Value Structure: { "pod-name-1.namespace": "1703123456", "pod-name-2.namespace": "1703123789" }3.5 Prefix Cache 插件(前缀缓存插件)一种基于 长前缀缓存 的感知调度策略。架构设计:三层映射:模型 (Model) → 哈希 (Hash) → Pod。基于 LRU 的缓存淘汰:实现高效的内存管理。Top-K 前缀匹配策略:返回具有最长前缀匹配的前 N 个 Pod。主要特性:字节级前缀匹配算法。优化的内存级 LRU 实现。缓存容量和候选 Pod 数量可配置。3.6 Random 插件(随机插件)一种 轻量级的随机负载均衡策略。实现方式:生成均匀分布的随机分数: Score ~ Uniform(0, 100)采用线程安全的独立随机数生成器。无状态设计,确保长期的负载分布均衡。适用场景:模式不明显的混合工作负载。追求极低调度开销的轻量级部署。作为性能对比的基准线(Baseline)。4. 实验设计与性能评估 4.1 实验步骤为了验证不同插件组合的实际效果我们建立了一个标准化的测试环境:表 1: 实验环境配置4.2 性能测试结果分析4.2.1 长系统提示词场景 (4096 tokens)表 2: 性能指标 – Long Prompt在处理具有长固定前缀(System Prompt)的并发请求时,KVCacheAware + Least Request 组合表现出了压倒性优势:吞吐量 (Throughput): 提升了 2.73倍。由于大量请求命中了同一 Pod 上的缓存,避免了重复计算。TTFT (首字延迟): 降低了 73.5%。缓存命中意味着 Prefill 阶段几乎瞬间完成,用户感知的响应速度极大提升。4.2.2 短系统提示词场景 (256 tokens)表 3: 性能指标 – Short Prompt在短示词场景下,各插件表现相对平稳,但 Least Request 依然在保持负载均衡、防止单点过热方面优于传统的 RoundRobin。5. 场景化部署建议 5.1 高缓存命中场景推荐配置:KVCacheAware 插件(KV缓存感知) + Least Request 插件(最少请求)适用用例:智能客服机器人、代码生成以及类似的高度结构化工作负载。带有长系统提示词(System Prompts)的多轮对话。基于模板的内容生成服务。5.2 常规负载均衡场景推荐配置:Least Request 插件(最少请求) + Least Latency 插件(最低延迟)适用用例:具有多样化请求模式的通用推理服务。需要公平分配资源的多租户环境。实时交互式应用。5.3 资源受限环境推荐配置:GPU Cache Usage 插件(GPU缓存使用率)适用用例:显存(GPU Memory)有限的边缘计算部署。对成本敏感的云端环境。多个模型共享底层 GPU 资源的场景。6. 总 结 Kthena 通过 ScorePlugin 机制,将原本复杂的推理调度逻辑拆解为可组合的模块。实验证明:缓存感知 (KV Cache Awareness) 是提升 LLM 推理效率的关键,尤其是在 RAG(检索增强生成)和长文本场景中。多插件协同(如 KVCache + Least Request)能够兼顾“缓存复用”与“负载均衡”,达到最优的综合性能。作为 Volcano 的子项目,Kthena 致力于将 Volcano 的调度优势从 AI 训练扩展到推理领域,为企业提供从训练到推理的完整全栈解决方案。 🌋 Kthena GitHub地址:cid:link_0 🌋 更多信息,欢迎访问 Volcano 官网: https://volcano.sh 欢迎Star★,Fork,来 Kthena 社区一起玩转LLM推理!扫码回复“Kthena” 进入技术群
-
作者 | Rain Zhang; Qi Zhang; Jian HuangAgent Harness 在云原生托管架构落地的核心意义在于实现弹性、效率与运维的全面优化。借助云原生的虚拟化、容器化与动态编排能力,Agent Harness 能够打破资源闲置的瓶颈,实现按需自动扩缩容,显著降低计算成本。同时,云原生的声明式 API 和服务自愈机制,将复杂的生命周期管理转化为自动化运维,极大减轻了人工负担。此外,依托统一的可观测性与标准化交付流程,Agent Harness 可以无缝集成现有技术生态,加速 AI 代理从原型到生产级应用的转化,从而为企业提供高可靠、低成本且易于治理的智能服务运行底座。▍1. Agent Harness 面向云原生托管的落地挑战当前 Agent Harness 在面向云原生托管架构落地过程中,主要面临冷启动延迟、状态持久化与执行安全三个维度的核心挑战,业界主流方案正通过架构解耦、轻量级虚拟化以及工程化治理来系统性地加以应对。首先,在冷启动延迟和资源浪费方面,传统虚拟机或容器的启动往往需要数秒时间,难以满足 AI 交互场景对实时性的严苛要求。其结果表现为用户等待时间被拉长,使用体验受到明显影响。为了降低延迟,不少系统采用预留“热池”的方式,但这又导致资源利用率在闲时极低,资源浪费严重,而当突发流量来临时,系统的性能表现也不够稳定。其次, 在稳定性与成本控制方面,问题主要体现在上下文窗口的有限性与状态执行的脆弱性上。由于上下文窗口存在上限,任务运行时间较长时容易出现“遗忘”或崩溃现象。一旦沙箱发生故障,正在执行的任务便会直接终止,长任务因此中断且无法恢复,进而引发记忆混乱、运维负担加重以及成本失控等问题。最后,在安全隔离方面,主要风险来自不可信代码的执行以及凭据的泄露。大语言模型生成的代码本身不可信,存在逃逸的潜在威胁。如果凭据与可执行代码同处一个沙箱环境中,提示词注入攻击便可能导致密钥泄露,进而引发系统被破坏、数据泄露、跳板攻击以及权限越级滥用等严重后果。 ▍2. 面向云原生托管 Agent Harness Infrastructure 的设计为了解决上述痛点,华为云托管的 Agent Harness 提出了从架构设计到 Agent Infrastructure 基础设施的解决方案。 对于企业而言, Agent Infrastructure基础设施不再将精力耗费在维护脆弱的单体容器上,而应转向构建 Agent 沙箱容量规划与并行调度、Agent 协调层和执行层架构解耦、具备极简轻量、极速启动、自动恢复能力和安全隔离的 Serverless 沙箱环境。图 1. Agent 猎鹰调度与羽量沙箱Agent 沙箱并行规划与调度通过采用容量预测技术,对 Agent 资源进行精准画像与预热管理。与传统基于时序的算法相比,该模型将拟合精准度提升30%,资源碎片率降低25%,利用率提高10%。在并行调度方面,系统基于资源碎片率、资源余量和预热分配量三个维度的因素,采用分片并行调度机制,使调度吞吐量显著提升至原来的5倍。在生态主导方面,项目在 CNCF 社区内主导了 Volcano 沙箱调度器生态的建设,吸引了超过200家公司参与使用,形成了良好的社区影响力与客户基础。Agent 协调层和执行层架构解耦,实现自动恢复能力采纳轻量级虚拟化技术(microVM),将 Agent Harness 协调层 与 Sandbox 执行层 彻底解耦,支持 Serverless 按需模式,配置合理的闲置超时回收策略。通过 SessionID 保证多轮对话路由到同一实例维持状态,并将会话日志外置持久化。Harness 故障后,新实例可重放日志恢复任务,实现“断点续传”。图 2. Agent Runtime 运行时架构安全隔离使用 microVM 级 VMM(CloudHypervisor),最小化设备集和每 VM 进程开销(3‑13MiB量级)。在单节点数千并发沙箱规模下,通过 microVM、定制 Guest 环境和动态资源控制,实现 VM 级安全隔离与高密度的兼得。强制隔离 Harness 与 Sandbox,实施最小权限原则与凭据托管。极简轻量华为云针对 Agent 与容器场景进行了极致优化,构建了由“基础操作系统 ContainerOS + 动态生成操作系统 On-the-fly OS”相结合的组合方案, 实现羽量级虚拟化,匹配 Agent 和 Serverless 场景对开销和速度的极致诉求。其中,ContainerOS 仅包含运行容器所必需的基础服务,On-the-fly OS 根据 Agent 运行需求组装和构建所需的 OS 的增量系统 。该方案采用轻量化的内核与根文件系统,可实现秒级启动,且空载状态下的内存占用低于50M字节。作为不可变基础设施,基础操作系统的根文件系统为只读,并以镜像为粒度进行原子化的升级与回滚操作。极速启动通过对 Sandbox 依赖资源及关键流程的预置,系统在计算、网络、存储及启动文件等方面提前准备,将资源准备时间从秒级压缩至毫秒级。在启动优化方面,采用操作系统裁剪与共享内存技术加速虚拟机启动,同时结合快照启动、Fork 机制以及容器组件的预热与重用,使实例创建时间从十秒级缩短至100毫秒。此外,基于预热实例的分层管理能力,系统根据供给性能构建分层预热池,并依据客户使用特征持续优化预热策略,最终将预热命中率提升至冷启动实例占比的80%。图3. Agent Sandbox 启动过程 ▍3. 工作展望:面向 AI Agent 与 Serverless 场景的极致高效、低成本的云原生沙箱体系围绕云原生架构, 后续工作会持续打磨优化 AI Agent 与 Serverless 场景的极致高效、低成本的安全沙箱体系,核心方案围绕以下三个目标展开:图4. 基于预调度 + Snapstart + lazyloading的microVM启动首先,为了应对云原生时代不同场景对安全隔离与弹性效率的多样化需求,以 CNCF (云原生计算基金会)旗下的多沙箱容器运行时项目 Kuasar 为底座,通过采用单 VM 单应用的极简架构,并剔除 Guest Agent 等冗余组件,打造出轻量化的 Appliance Sandbox 模式,目标是使单沙箱的底噪降低20%。图5. 云原生计算基金会CNCF多沙箱容器运行时项目Kuasar其次,为了实现亚秒级甚至百毫秒内的极速启动,方案扩展了 VMM 以支持基于 UFFD 的内存缺页 Hook,实现内存懒加载,并将 Snapstart 作为 Kuasar 的标准启动方式,同时结合虚拟机内存只读页面的复用技术,在降低资源消耗的同时确保单沙箱启动延迟小于100毫秒。最后,为了支撑大规模、高并发的创建需求,即持续10分钟每分钟创建10万个沙箱,方案设计了一个基于块级复用与内容寻址技术的镜像分发底座。该底座在多租户云系统中,将不同租户的镜像数据切块并计算指纹:相同指纹的数据块在多租户间复用,不同指纹的则按租户隔离存储,同时通过全链路块级加密保障安全合规。最终,这一设计在同构工作负载下实现了10倍的存储与带宽缩减,大幅降低了总成本,达成了成本优化与安全合规的双重竞争力。图6. microVM 的快速启动和批量创建 ▍4. 总结面向云原生托管的 Agent Harness 为企业提供了一套完整的 Agent 基础设施解决方案,核心在于将精力从维护单体容器转向构建 Serverless 沙箱环境。该方案通过容量预测与分片并行调度,显著提升了资源利用率和调度吞吐量;利用轻量级虚拟化技术实现协调层与执行层解耦,支持断点续传的自动恢复。在安全方面,采用 microVM 级隔离实现高并发下的安全防护。同时,通过组合式轻量操作系统实现低内存占用与秒级启动,并借助资源预置、快照及预热重用等优化,将实例创建时间缩短至100毫秒,预热命中率达冷启动的80%,从而构建出极简轻量、极速启动且安全隔离的沙箱环境。 关注魔方公众号,获取更多前沿资讯添加社区小助手k8s2222,进入技术交流群
-
一次典型的 Code Interpreter 调用,往往从一个很小的动作开始:用户点击“运行代码”。但在一个原生 Kubernetes 环境中,这个动作背后通常意味着一整套秒级链路:调度 Pod、分配网络、拉取镜像、启动容器。对于需要多步推理、频繁调用工具、强依赖交互体验的 AI Agent 应用来说,这样的启动路径并不自然。这也是 AgentCube 试图解决的问题:在 Kubernetes 的算力底座之上,补齐面向 Agent 工作负载的关键机制缺口,提供一层真正理解会话、沙箱和工具调用语义的 Serverless 编排层。AgentCube(cid:link_2) 提供了一组可直接落地的核心机制。本文重点展开这些能力在实现层面的设计取舍:会话如何绑定沙箱、预热池如何消除冷启动、PicoD 如何替代 SSH、JWT 安全链如何保护外部访问,以及系统如何自动回收不再活跃的沙箱资源。 从 Kubernetes 到 Agent Native 随着大语言模型(LLM)技术的成熟,技术架构正从“无状态推理”向“自主智能体(Autonomous Agents)”演进。Kubernetes 凭借成熟的生态和对异构算力的标准化管理,已经成为构建 AI 基础设施的事实标准。但在面对 AI Agent 这种“高并发、短时效、强状态依赖”的新型负载时,原生 Kubernetes 仍存在几类明显的粒度错配与机制缺位。启动延迟与交互体验的矛盾。 Agent 的交互通常要求毫秒级响应,而原生 K8s Pod 的启动流程往往是秒级甚至分钟级。对于需要频繁拉起 Code Interpreter 或临时子 Agent 的场景,这样的冷启动延迟很难被终端用户接受。资源利用率的挑战。 Agent 是典型的 IO 密集型负载。在一次会话中,大量时间都消耗在等待 LLM 返回 Token 或等待外部工具响应。如果在 K8s 上为每个 Agent 独占一个 Pod,CPU 和内存资源会在等待期间被大量闲置。会话状态管理的缺失。 K8s 对无状态工作负载天然友好,但 Agent 高度依赖上下文(Context / Memory)。Pod 的重建意味着内存态上下文的丢失,开发者被迫在应用层额外拼接外部状态存储,系统复杂度和网络开销都会随之上升。安全隔离难题。 高级 Agent(如 Data Analyst)需要运行由 LLM 生成的不可信代码。普通的 runC 容器很难为这种场景提供足够强的隔离边界,企业级 Agent 平台需要一种既能快速启动、又具备强隔离能力的沙箱环境。围绕这些问题,AgentCube 给出了一组明确的工程实现:Kubernetes 面临的缺口AgentCube 的对应机制冷启动延迟高Warm Pool 预热池,提前准备可分配的沙箱实例会话请求需要保持上下文Session ID 到沙箱实例的绑定式路由不可信代码执行风险高MicroVM 沙箱 + PicoD 执行面 + JWT 认证链会话结束后资源容易堆积基于空闲超时和绝对时长的双策略 GCAgentCube 不是简单增加几条 CRD,而是在 Kubernetes 之上补上一层面向 Agent 工作负载的运行时与编排机制。 整体架构 AgentCube 的核心架构可以分为三部分:数据平面(Router)、控制平面(Workload Manager) 和 沙箱执行面(PicoD)。系统通过 Redis/Valkey 维护会话状态和索引,使不同组件可以独立扩展。图 1:AgentCube 整体架构 —— Router 接收请求并路由至沙箱,Workload Manager 管理沙箱生命周期,PicoD 负责沙箱内执行核心组件一览:组件角色关键能力AgentCube Router数据平面入口HTTP 反向代理、会话路由、JWT 签名、并发控制Workload Manager控制平面沙箱创建/删除、预热池管理、双策略 GCPicoD沙箱内守护进程代码执行、文件 I/O、JWT 认证、路径沙箱化Session Store状态存储Redis/Valkey 支持,Sorted Set 索引加速查询一次典型请求的大致链路如下:+----------+ +----------+ +------------------+ | Client | --- 1) HTTP ---> | Router | --- 2) alloc --> | Workload Manager | +----------+ +----+-----+ +--------+---------+ | | 4) sign JWT 3) create/claim + proxy Sandbox Pod | | v v +--------+ +-------------+ | PicoD | <-- running in --- | Sandbox Pod | +---+----+ +-------------+ | 5) verify JWT execute cmd return result | v stdout / stderr / exit_code图中的 Sandbox Pod 底层是由 Kuasar 调用 CloudHypervisor 拉起的 MicroVM,PicoD 作为守护进程运行在 MicroVM 内部,负责接收来自 Router 的请求并在隔离环境中执行。 核心特性深度解读 一、Session-Based MicroVM Routing:让会话真正绑定执行环境AI Agent 工作负载的一个本质特征,是有状态、交互式,并且可能跨越多次调用。一次完整的任务往往包含多步推理、工具调用、环境探查和中间结果写入。如果每个请求都被路由到新的执行环境,上下文就无法自然延续。AgentCube 通过 Session ID -> 沙箱实例 的绑定关系解决这个问题:客户端首次调用时不携带 x-agentcube-session-id,Router 会为其分配新的沙箱实例响应头中返回 x-agentcube-session-id客户端后续请求携带该 Session ID,即可继续命中同一个会话沙箱从客户端视角看,整个过程是透明的。它不需要理解底层沙箱的生命周期,只需要在多轮调用中带上同一个 Session ID。Router 基于 Gin 构建,核心 handler handleInvoke() 的逻辑大致如下:// 从请求头提取 Session ID sessionID := c.GetHeader("x-agentcube-session-id") // 通过 SessionManager 查找或创建沙箱 sandbox, err := s.sessionManager.GetSandboxBySession( c.Request.Context(), sessionID, namespace, name, kind) // 更新会话最后活跃时间(用于 GC 判定) s.storeClient.UpdateSessionLastActivity(ctx, sandbox.SessionID, time.Now()) // 反向代理转发至沙箱 s.forwardToSandbox(c, sandbox, path)Router 同时支持 HTTP/2 (h2c) 透传,并内置可配置的并发请求上限(默认 1000),避免突发流量直接冲垮后端沙箱集群。当前暴露的调用入口包括:POST /v1/namespaces/{namespace}/agent-runtimes/{name}/invocations/*path GET /v1/namespaces/{namespace}/agent-runtimes/{name}/invocations/*path POST /v1/namespaces/{namespace}/code-interpreters/{name}/invocations/*path GET /v1/namespaces/{namespace}/code-interpreters/{name}/invocations/*path二、两种 CRD:两种工作负载抽象AgentCube 在 Kubernetes 之上引入了两类核心 CRD,对应 AI Agent 领域里两种典型的运行模式:一种强调通用能力与灵活性,一种强调安全默认与沙箱约束。AgentRuntime:面向通用 Agent 的运行时抽象AgentRuntime 面向需要完整 Kubernetes 能力的对话式或工具调用型 Agent。它接受完整的 PodSpec 模板,因此可以挂载 Volume、注入凭据、配置 Sidecar 容器。apiVersion: runtime.agentcube.volcano.sh/v1alpha1 kind: AgentRuntime metadata: name: my-agent spec: podTemplate: containers: - name: agent image: my-agent:latest ports: - containerPort: 8080 targetPort: - pathPrefix: "/" port: 8080 protocol: HTTP sessionTimeout: 15m maxSessionDuration: 8hCodeInterpreter:面向安全代码执行的受约束抽象CodeInterpreter 更适合 Notebook、REPL、“运行代码”按钮等多租户安全执行场景。相比 AgentRuntime,它采用更受约束的模板能力,以便将隔离、运行时和资源限制统一收敛到更安全的默认值。apiVersion: runtime.agentcube.volcano.sh/v1alpha1 kind: CodeInterpreter metadata: name: my-interpreter spec: template: image: ghcr.io/volcano-sh/picod:latest runtimeClassName: kata resources: requests: { cpu: "500m", memory: "512Mi" } limits: { cpu: "2", memory: "2Gi" } warmPoolSize: 3 authMode: picod sessionTimeout: 15m maxSessionDuration: 8h两者的核心差异在于:AgentRuntime 更开放,优先满足复杂 Agent 应用的组合能力CodeInterpreter 更收敛,优先满足安全沙箱场景的开箱即用三、Warm Pool:预热池如何消除冷启动从零创建沙箱实例,会不可避免地引入启动延迟。对于交互式 Agent 场景,这种等待通常是用户最直接感知到的体验问题。为此,AgentCube 引入了 Warm Pool 预热池机制。+-----------------------------------------------------------+ | Warm Pool | | | | +-----------+ +-----------+ +-----------+ | | | Sandbox | | Sandbox | | Sandbox | <- idle | | | (idle) | | (idle) | | (idle) | | | +-----+-----+ +-----------+ +-----------+ | | | | | v new session --> SandboxClaim | | +-----------+ | | | Sandbox | <- claimed, ready to use | | | (active) | | | +-----------+ | | | | pool replenishes asynchronously | +-----------------------------------------------------------+Workload Manager 中的 CodeInterpreterReconciler 通过三层 CRD 协作完成这一机制:1. SandboxTemplate:定义沙箱实例模板,并注入 PicoD 所需的认证公钥2. SandboxWarmPool:声明预热副本数,维持一组可被直接认领的空闲实例3. SandboxClaim:新会话到来时,从池中认领一个已就绪实例这种做法的好处,是将“创建实例”和“分配实例”解耦。沙箱启动的慢路径前置到后台完成,用户请求只需走认领路径,因此可以显著缩短首跳延迟。整个过程是幂等的。Reconciler 在调和循环中只对不一致状态做最小变更,这也使 Warm Pool 的管理方式天然贴合 Kubernetes 声明式控制器的工作模型。面向更进一步的启动加速,社区后续计划集成 Kuasar Snapstart,通过内存快照进一步将沙箱就绪时间从秒级压缩至百毫秒量级。四、PicoD:替代 SSH 的轻量级沙箱守护进程传统代码沙箱方案通常依赖 SSH 进行远程执行。但对一个本质上是单请求 RPC 的场景来说,SSH 会引入过重的协议开销,包括密钥管理、多路复用协商和持久会话维护。PicoD(Pico Daemon)就是在这样的背景下被引入的。它运行在沙箱内部,通过一组精简的 HTTP API 代替 SSH,完成命令执行、文件读写和健康检查等操作。API 端点方法功能/api/executePOST执行任意命令,支持超时、工作目录、环境变量/api/filesPOST文件上传或写入(multipart 或 base64 JSON)/api/files/*pathGET文件下载或读取,支持流式传输/healthGET健康检查(免认证)PicoD 运行在 MicroVM 内部,外部请求在触达它之前已经穿越了 VM 级隔离边界。Router 对每个请求签发短期 JWT,PicoD 校验通过后才执行——这道认证门与 MicroVM 隔离分别在两个层次上独立生效。其执行逻辑的核心实现大致如下:ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() cmd := exec.CommandContext(ctx, command[0], command[1:]...) cmd.Dir = workspaceDir cmd.Env = mergedEnv if ctx.Err() == context.DeadlineExceeded { exitCode = 124 }对应的防护措施包括:路径沙箱化:通过 sanitizePath() 将文件访问限制在指定 workspace 根目录下请求体大小限制:默认 32 MB,防止恶意请求耗尽内存无状态处理模型:每个请求独立处理,避免持久连接带来的额外攻击面五、JWT 安全链:外部访问沙箱时,如何建立信任沙箱实例是临时资源,会随时被创建和销毁。如果在集群中直接分发共享密钥,密钥轮换和安全边界都会变得脆弱。为此,AgentCube 在 Router 与 PicoD 之间建立了一条基于 RSA 非对称加密 的认证链。+--------------+ +-------------------------+ | Router | | Kubernetes Secret | | | generate on boot | picod-router-identity | | RSA-2048 | ------------------> | | | key pair | | private.pem (Router) | | | | public.pem (PicoD) | +------+-------+ +------------+------------+ | | | sign with Workload Manager injects | private key PICOD_AUTH_PUBLIC_KEY | (5min TTL) into sandbox env | | v v +--------------+ RS256 JWT Token +--------------+ | Router signs | ------------------> | PicoD verify | | (private key)| | (public key) | +--------------+ +--------------+这条链路解决的是访问认证问题:Router 对外接收请求,对内使用私钥签发短时有效的 JWT;PicoD 持有公钥,负责校验请求是否合法。关键设计点包括:5 分钟短有效期:即使 Token 泄漏,影响范围也能被压缩到很小1 分钟时钟漂移容忍:兼顾分布式环境中的时钟偏差私钥不出 Router:PicoD 仅做校验,不持有签发能力启动时自动生成并注入:降低运维配置复杂度六、双策略 GC:如何回收不再活跃的沙箱在 Agent 场景下,资源创建不是难点,难点在于如何及时、稳定地回收已经闲置的沙箱。如果会话终止后资源不能自动回收,集群最终会被大量“已经没人使用、但仍然占资源”的实例拖垮。为此,AgentCube 在 Workload Manager 中实现了双重垃圾回收策略:策略触发条件默认值空闲超时(Idle TTL)沙在 sessionTimeout 内无任何请求15 分钟绝对最大时长(Max Duration)沙箱创建时间超过 maxSessionDuration8 小时GC 循环每 15 秒执行一次,每轮最多检查 100 个候选沙箱,避免单次 GC 扫描时间过长。底层索引结构基于 Redis Sorted Set:session:{sessionID} -> SandboxInfo JSON session:expiry -> Sorted Set (score = 到期时间戳) session:last_activity -> Sorted Set (score = 最后活跃时间)这种设计让系统可以用 ZRANGEBYSCORE 高效找出已过期或长期不活跃的会话。删除时,GC 会同时清理 Kubernetes 中的 Sandbox / SandboxClaim 资源和 Redis 中的会话记录,避免出现“实例删了但索引还在”或“索引删了但实例还活着”的不一致状态。 生态集成 除了运行时和沙箱机制,AgentCube 还提供了面向上层框架的接入能力,使应用开发者不需要直接处理底层基础设施细节。Python SDKfrom agentcube import CodeInterpreterClient interpreter = CodeInterpreterClient() result = interpreter.run_code("python", "print('Hello, AgentCube!')") print(result) interpreter.write_file(content="data", remote_path="/workspace/data.txt") interpreter.download_file("/workspace/data.txt", "./local_data.txt")LangChain / LangGraph 集成AgentCube 可以作为 LangChain 的 @tool 接入 ReAct Agent 工作流,将代码执行部分自然下沉到受隔离的沙箱环境中,应用层无需直接理解底层实例调度和生命周期管理。Dify 插件项目仓库中的 dify-plugin 目录提供了 Dify 工具接入方式,使 Dify 用户也可以直接消费 AgentCube 的沙箱能力。 快速上手 前置条件Kubernetes 集群 v1.24+Redis 或 Valkey 实例sigs.k8s.io/agent-sandbox v0.1.1 CRD 已安装Helm 安装helm install agentcube manifests/charts/base \ --namespace agentcube-system --create-namespace \ --set redis.addr=<redis-host>:6379 \ --set redis.password="<password>"创建第一个 CodeInterpreterapiVersion: runtime.agentcube.volcano.sh/v1alpha1 kind: CodeInterpreter metadata: name: my-interpreter namespace: default spec: template: image: ghcr.io/volcano-sh/picod:latest resources: requests: { cpu: "500m", memory: "512Mi" } limits: { cpu: "2", memory: "2Gi" } warmPoolSize: 2 sessionTimeout: 15m maxSessionDuration: 8h发起调用curl -X POST \ http://<router-host>/v1/namespaces/default/code-interpreters/my-interpreter/invocations/api/execute \ -H "Content-Type: application/json" \ -d '{"command": ["python3", "-c", "print(1+1)"]}'响应头中的 x-agentcube-session-id 即为会话 ID。后续请求继续携带它,就可以复用同一个沙箱执行环境。 致 谢 从项目启动到今天,AgentCube 已经吸引了多位社区开发者参与共建。感谢所有为 AgentCube 做出贡献的开发者:@YaoZengzeng@acsoto@hzxuzhonghu@Sagar-6203620715@mahil-2040@t2wang@FAUST-BENCHOU@tjucoder@LaynePeng@yashisrani@katara-Jayprakash@LiZhenCheng9527@Tweakzx@warjiang@LeslieKuo@MahaoAlex@VanderChen@kevin-wangzefeng@ifelseend@cairon-ab@RushabhMehta2005@Sanchit2662@qizha@ssfffss@wjf295004046@Aman-Cool@Storm1289@sicaario 相关链接[1] GitHub 仓库: cid:link_2[2] Volcano 官网: https://volcano.sh[3] 设计文档: cid:link_0[4] Python SDK: cid:link_1AgentCube 开源项目欢迎广大开发者参与。无论是提交 Issue、贡献 PR,还是在你的项目中试用 AgentCube,都是对项目的支持。 关注魔方公众号,获取更多前沿资讯添加社区小助手k8s2222,进入技术交流群
-
随着大语言模型(LLM)成为现代 AI 应用的核心引擎,支撑其运行的基础设施范式也随之进化。在解决了“智能路由”与“模型编排”等空间维度的请求分发问题后,运维的核心焦点转向了时间维度的资源博弈:如何实时、动态地确定最佳推理实例规模?Kthena Autoscaler 便是针对这一命题的标准答案。作为内置于 kthena-controller-manager 的核心控制器,它深度集成于 Kubernetes 生态,能够基于实时负载特征自动平滑地调整推理服务实例数。其核心价值在于:在严守业务 SLO(服务等级目标)红线的同时,最大化榨取计算资源的利用效率。本文将深入剖析 Kthena Autoscaler 的架构拓扑、通用策略逻辑以及多样化的绑定形态。 ▍1. 为什么 LLM 推理需要专用弹性伸缩?LLM 推理工作负载具有独特的特征,对传统弹性伸缩方案提出挑战:特征对伸缩的影响业务指标驱动相比于 CPU/内存利用率,推理引擎(如 vLLM)暴露的队列长度、KV Cache 利用率等业务指标更能直接反映服务饱和度。突发流量模式用户请求突然激增时需要快速扩容以维持延迟 SLOPrefill/Decode 不对称PD 解耦部署需要对预填和解码角色进行独立且灵活的伸缩。异构硬件与成本不同实例类型(GPU/NPU)提供不同的性能/成本权衡,需要精细化调度。传统的 Kubernetes HPA 或 KEDA 缺乏针对 LLM 工作负载的模型感知能力。Kthena Autoscaler 通过 直连 Pod 采集业务指标、角色级伸缩支持 以及 成本感知优化算法 弥合了这一差距。 ▍2. 架构概览Kthena Autoscaler 遵循控制器模式,作为 kthena-controller-manager 的子控制器运行。它通过直接采集 Pod 业务指标,结合用户定义的策略进行闭环控制。▍3. 通用策略 (AutoscalingPolicy):定义“如何缩容”AutoscalingPolicy 是一个通用的逻辑模板,定义了计算副本需求的核心大脑。3.1 核心指标与容差Autoscaler 允许直接从 Pod 的 /metrics 端点抓取推理专属指标。这意味着它能感知到 vLLM 内部的请求队列状态。常见指标包括:vllm:num_requests_waiting:等待队列长度(最核心指标)。vllm:kv_cache_usage_perc:KV Cache 利用率。通过 targetValue 设置目标值,并利用 tolerancePercent(容差带)防止在目标值附近的微小抖动触发频繁伸缩。3.2 伸缩行为:稳定模式与紧急模式为了应对推理场景的流量特性,Policy 支持双模式策略:稳定模式 (Stable Mode):使用较长的稳定窗口(如 1 分钟)观察持续趋势,避免对瞬时波动过度反应。紧急模式 (Panic Mode):当指标严重偏离目标(如超过 150%)时触发,绕过稳定窗口实现秒级快速扩容。apiVersion: workload.serving.volcano.sh/v1alpha1kind:AutoscalingPolicymetadata: name:vllm-queue-policyspec: metrics: - metricName:vllm:num_requests_waiting targetValue:100 tolerancePercent:50 behavior: scaleUp: stablePolicy: stabilizationWindow:1m period:30s scaleDown: stabilizationWindow:5m period: 1m3.3 成本感知优化算法当伸缩涉及多个实例类型或硬件时,Policy 底层的算法引擎会执行带倍增策略的贪心算法。该算法根据每种实例类型的单位成本 (Cost) 将容量划分为指数级批次(基于 costExpansionRate),并按成本升序排序生成伸缩序列。这确保了:成本效率:优先选择低成本实例。减少冷启动:序列在周期内保持稳定,优先复用已运行的实例。 ▍4. 伸缩绑定 (AutoscalingPolicyBinding):定义“缩容什么”AutoscalingPolicyBinding 是连接通用策略与具体目标的“粘合剂”。通过不同的绑定目标,可以实现完全不同的伸缩形态。4.1 作用于 ServingGroup:实现固定 PD 比例伸缩这是最常见的形态。通过target将 Policy 绑定到 ModelServing 或其中的 ServingGroup。逻辑:Autoscaler 将整组作为一个整体进行扩缩。效果:系统会严格保持定义的 Role 比例(如 prefill:decode = 1:2)同步增减。这适用于 PD 拓扑固定的标准部署场景。# 绑定到 ModelServing (整组同步伸缩)apiVersion:workload.serving.volcano.sh/v1alpha1kind:AutoscalingPolicyBindingmetadata: name:vllm-group-bindingspec: policyRef: name:vllm-queue-policy homogeneousTarget: target: targetRef: kind:ModelServing name:vllm-llama3 minReplicas:1 maxReplicas: 104.2 作用于 Role:实现独立 PD 异构伸缩AutoScaler通过subTargets,能够将 Policy 绑定到 ModelServing 内特定的 Role(如仅绑定 decode 角色)。逻辑:Autoscaler 仅针对该特定角色计算并修改副本数。效果:可以实现 prefill 副本保持稳定,而 decode 副本根据长输出负载独立增加。反过来说,也可以实现decode副本保持稳定,扩缩prefill副本数。这种PD 异构伸缩能极大提高资源利用率。# 包含 Role 定义的 ModelServing 示例apiVersion:workload.serving.volcano.sh/v1alpha1kind:ModelServingmetadata: name:deepseek-servingspec: template: roles: - name:prefill replicas:1 # ... 容器配置 ... - name:decode replicas:2 # ... 容器配置 ...---# 独立绑定到 Role 的示例apiVersion:workload.serving.volcano.sh/v1alpha1kind:AutoscalingPolicyBindingmetadata: name:decode-independent-bindingspec: policyRef: name:llm-scaling-policy homogeneousTarget: target: targetRef: kind:ModelServing name:deepseek-serving subTargets: kind:Role name:decode# 仅针对 decode 角色独立伸缩 minReplicas:2 maxReplicas: 8 ▍5. 最佳实践与故障排查配置建议保守起步:初始配置使用较宽容差带 (15-20%) 和较长稳定窗口。角色差异化目标:在 PD 异构场景下,为 decode 角色设置比 prefill 更敏感的阈值。成本校准:异构伸缩时,根据实际云定价或 TCO 调整 cost 值。可观测性Kthena Autoscaler 在 /metrics 暴露以下指标:kthena_autoscaler_desired_replicas:决策后的目标副本数。kthena_autoscaler_current_replicas:实际观测到的副本数。kthena_autoscaler_scaling_events_total:伸缩动作计数器。 ▍6. 进阶:成本感知优化与异构伸缩示例在实际生产中,我们往往拥有不同规格的 GPU 资源。Kthena Autoscaler 的 heterogeneousTarget 允许在多个目标之间进行成本优先的伸缩分配。# 跨硬件成本优化绑定示例apiVersion:workload.serving.volcano.sh/v1alpha1kind:AutoscalingPolicyBindingmetadata: name:heterogeneous-cost-bindingspec: policyRef: name:vllm-queue-policy heterogeneousTarget: params: - target: targetRef: kind:ModelServing name:deepseek-h100# 性能高,成本高 cost:100 minReplicas:1 maxReplicas:10 - target: targetRef: kind:ModelServing name:deepseek-a100# 成本低,优先扩容 cost:50 minReplicas:1 maxReplicas:20 # 定义成本扩张率,影响算法对成本与容量的权衡 costExpansionRatePercent: 200通过配置不同的 cost 值,Autoscaler 的算法引擎会优先尝试在低成本资源上扩容,而在缩容时则优先保留高效率或特定成本的实例,从而在满足性能需求的同时实现最优 TCO。 ▍总结Kthena Autoscaler 通过将“伸缩逻辑 (Policy)”与“伸缩目标 (Binding)”解耦,提供了极大的灵活性。通过 ServingGroup 绑定可以实现稳定的固定比例扩缩,而通过 Role 绑定则能实现精细的异构扩缩。结合内置控制器的架构和成本感知算法,它为构建高效、低成本的 LLM 推理平台提供了坚实基础。 相关链接[1] Kthena 官方文档: https://kthena.volcano.sh[2] GitHub 仓库: cid:link_0欢迎Star★,Fork,来 Kthena 社区一起玩转LLM推理!关注魔方公众号,获取更多前沿资讯添加社区小助手k8s2222,进入Kthena技术交流群
-
Karmada 用户组再迎重要新成员,GMI Cloud[1]正式加入。作为云原生计算基金会(CNCF)旗下的项目,Karmada 致力于为用户提供强大的多集群管理和调度能力,帮助企业在复杂的分布式环境中实现高效的应用部署和管理。GMI Cloud 的加入将进一步加强 Karmada 社区,为项目的持续创新带来新的活力,标志着社区发展和 Karmada 在多样化生产环境中采用的又一个重要里程碑。 关于GMI Cloud GMI Cloud 是一款面向生产级人工智能推理场景打造的原生 AI 基础设施平台。从无服务器应用程序接口到专属 GPU 集群,GMI Cloud 依托英伟达 GPU 平台,可提供稳定可控的性能、弹性扩容的算力以及高性价比的运行服务。GMI Cloud 打造了全栈垂直整合的人工智能基础设施体系,覆盖推理接口、调度编排、算力计算至硬件设备的全链路环节。 关于 Karmada 用户组 Karmada 用户组是一个由在其环境中成功采用 Karmada 的组织和用户组成的社区。作为连接社区与用户的核心纽带,Karmada 用户组致力于打造一个深度融合、开放协作的高价值平台,推动成员间的高效联动与经验共享,助力云原生多云多集群生态系统的蓬勃发展。成为 Karmada 用户组成员具有以下优势:社区认可:作为云原生多集群管理领域的领导者来展示您的组织,在 CNCF 和 Karmada 社区中获得知名度;协作与交流:与其他采用者建立联系,分享最佳实践,并在实际用例和解决方案上进行协作;保持更新:及时接收重要更新通知,包括关键功能、错误修复和安全建议;活动参与:受邀参与 Karmada 相关活动,包括 KubeCon + CloudNativeCon、网络研讨会和聚会;职位发布:有机会在 Karmada 社区支持的职位公告板上发布与 Karmada 相关的职位空缺(暂不可用);扩展商业机会:与 Karmada 生态系统的其他成员建立潜在的商业联系和合作。您可以在 GitHub 社区仓库中了解更多关于 Karmada 用户组[2] 的信息, 并在 karmada.io/adopters [3] 查看完整的公开的采用者列表。截至目前,Karmada 用户组已吸纳来自全球的 40+ 家机构和组织。更多使用场景及案例研究请查阅:https://karmada.io/adopters 加入 Karmada 用户组 Karmada 用户组对当前正在生产环境中使用 Karmada 的最终用户和供应商开放。这包括:最终用户:在其生产环境中运行 Karmada 的组织;供应商:提供基于 Karmada 的产品或服务,并有客户在生产环境中使用这些产品或服务的公司。您是否在生产环境中使用 Karmada 并有兴趣加入 Karmada 用户组?访问下方 Karmada 用户组申请表单 [4],提交 issue 申请,即可接收申请进度。手机端可扫描下方二维码快捷填写申请表单。扫码申请加入用户组更多信息,请访问:[1] GMI Cloud: https://www.gmicloud.ai/[2] Karmada 用户组: https://github.com/karmada-io/community/tree/main/adopter-group[3] Karmada 采用者列表: http://karmada.io/adopters[4] Karmada 用户组申请表单: https://github.com/karmada-io/community/issues/new?template=adopter-group-application.yamlKarmada Adopter Group 欢迎您的加入!期待与您共同创建一个友好而活跃的空间,共享知识、最佳实践和经验,为企业与社区发展缔造更多可能。如需了解更多关于 Karmada Adopter Group 的信息,请联系:Maintainer Mailing Listcncf-karmada-maintainers@lists.cncf.io Karmada(https://karmada.io/)是 CNCF 首个跨云跨集群容器编排引擎,由华为云、工商银行、小红书、中国一汽等八家企业联合发起。Karmada的贡献企业与贡献者遍布全球 22 个国家和地区的 100 多个组织,包括华为、道客、浙江大学、腾讯、滴滴、Bloomberg、Yunhorn、携程等。截至目前,项目在 GitHub 上已获得 5.2k+Star。 关注魔方公众号,获取更多前沿资讯添加社区小助手k8s2222,进入技术交流群
-
由 Linux Foundation 组织的 LFX Mentorship 计划[1],从2019年开始为 CNCF 各个开源社区中的开发人员持续提供带薪实习和指导。该项目往年已获 2w+ 申请,发起 2000+ 课题,毕业实习生1400+,发放超过 380 万美金报酬。LFX Mentorship 2026 夏季(Term 2)申请时间为5月5日 – 5月19日(11:00 PDT;18:00 UTC),远程实习将从 6 月 8 日开始为期三个月。参与到 LFX Mentorship 计划中,为开源项目做贡献、获得开源社区的认可同时,完成工作还能获取报酬 (位于中国的开发者报酬为 3000 美金,约合 20000 人民币)。Karmada 社区在 LFX Mentorship 计划的课题申请正在火热进行中,感兴趣的开发者即日起可前往官方平台申请:https://mentorship.lfx.linuxfoundation.org/ Karmada 社区介绍 Karmada 是 CNCF 首个多云多集群容器编排项目。作为开放的多云多集群容器编排引擎,Karmada 旨在帮助用户在多云环境下部署和运维业务应用。凭借兼容 Kubernetes 原生 API 的能力,Karmada 可以平滑迁移单集群工作负载,并且仍可保持与 Kubernetes 周边生态工具链协同。Karmada 社区在 GitHub 上 Star 超过5.6k+,贡献者广泛分布于 20+国家和地区,现已在华为云、道客、兴业数金、中国移动、中国联通、携程、360集团、新浪、中通快递等众多企业单位生产应用,为企业提供从单集群到多云架构的平滑演进方案。社区地址:cid:link_0 面向对象 本期计划申请者需 2026 年 5 月 19 日前在 LFX 官网[1]完成 Mentee 注册及项目申请。若被接收作为 Mentee,您将能在开源社区经验丰富、积极贡献的 Mentor 指导下为开源项目做出贡献。依据官方规定,对 Mentee 申请者有以下要求[2]:在参加该计划时您至少年满 18 周岁所在单位和组织不禁止该实习未参加另外的 Linux Mentorship 计划开发者以个人身份参与(在校或已毕业均可)具备所注册国家中工作权利且所注册国家未被计划禁止 (中国已获许可)满足具体所属项目中提及的其它前置需求 课题参与方式 根据官方安排 [3],LFX Mentorship 2026 年 Term2 申请及实习流程如下:Mentee 注册与项目申请:5月5日-5月19日(11:00 AM PDT/18:00 UTC)申请者审核期: 5月20日-6月2日(11:00 AM PDT/18:00 UTC)申请者入选通知:6月3日实习正式开始:6月8日中期考核:7月21日(11:00 AM PDT/18:00 UTC)首次津贴支付:7月22日结项考核、实习报告提交:8月25日(11:00 AM PDT/18:00 UTC)最终津贴支付批准:8月26日本期结束最终日期:8月31日参与者如有意向如何申请?流程详见 [4]:https://docs.linuxfoundation.org/lfx/mentorship/mentee-guide/how-to-apply实习申请结果预计将在 6 月 3 日通知到申请人。主线开发日期为 2026 年 6 月 8 日-8 月 25 日,全程线上协作,无需线下参与。结项需要在 2026 年 8 月 25 日前以 PR 的形式提交到项目所在的开源社区仓库中并完成合并。 Karmada 项目课题 在 LFX Mentorship 2026 Term 2,Karmada社区的课题如下:▍Karmada: Build Agent Skills课题描述:Karmada 是一个多集群编排系统,当前的 AI 编程智能体尚未形成与该系统深度匹配的技能结构。在缺乏专用技能库的情况下,智能体往往需要依赖零散的文档、在不充分的上下文中推断策略行为,这可能导致生成的PropagationPolicy、OverridePolicy或排查建议不够准确。本课题旨在为 AI 编程智能体系统性地构建面向 Karmada 的技能集。整体设计沿用成熟的“多技能库”模式,包含共享知识库、面向工作流的专项技能,以及用于处理格式敏感任务的确定性辅助工具。预期产出:一个共享知识库,涵盖策略 API、策略模式、故障排查案例、组件指南以及可复用的示例。用于策略生成、策略评审、放置解释、传播调试以及多集群管理的确定性辅助脚本、测试夹具和示例场景。面向贡献者的文档,说明如何在 hack/agent-skills/ 下新增技能、示例和知识文件。前置技能:Go; Kubernetes; React; CI/CD Systems ( GitHub Actions); Document tools课题导师:Hongcai Ren(@RainbowMango )qdurenhongcai@gmail.comZhen Chang (@XiShanYongYe-Chang )changzhen5@huawei.com课题申请入口:https://mentorship.lfx.linuxfoundation.org/project/12821d1d-9528-4cf3-ac3c-d57a6b585599对课题内容有任何问题,欢迎直接向课题导师发送邮件或在GitHub仓库提交Issue提问。扫码回复“Karmada” 进入技术群今年夏季,Karmada社区期待在 LFX Mentorship 见到您!附:申报指引[1] LFX Mentorship计划官网及申报入口: https://mentorship.lfx.linuxfoundation.org/#projects_all[2] LFX Mentorship - Application Requirement: https://docs.linuxfoundation.org/lfx/mentorship/mentee-guide/am-i-eligible[3] LFX Mentorship - Program Readme: https://github.com/cncf/mentoring/blob/main/programs/lfx-mentorship/2026/02-Jun-Aug/README.md[4] LFX Mentorship - Mentee Application Guideline: https://docs.linuxfoundation.org/lfx/mentorship/mentee-guide/how-to-apply
-
欢迎阅读「从零开始理解大模型」系列 —— 十篇文章,从"下一个词预测"到完整的大模型心智模型。每篇配可运行代码。第一篇:一切从"猜下一个词"开始第二篇:Token——大模型眼中的"字"长什么样第三篇:向量与 Embedding——把文字变成数学第四篇:Attention——大模型的"阅读理解"机制第五篇:Transformer 全景——积木怎么搭成大厦第六篇:训练——70 亿个参数是怎么"学"出来的第七篇:推理——你按下回车后的这一秒发生了什么第八篇:上下文窗口——大模型的"工作记忆"第九篇:Scaling Law——为什么"大力出奇迹"有效第十篇:从大模型到 Agent——下一个词预测如何长出手脚* 本系列配套运行代码,可在公众号后台回复“大模型”完整获取。作者:十一前五篇讲的是大模型的"身体结构"——Token、Embedding、Attention、FFN 怎么组装在一起。但结构只是骨架,参数才是灵魂。一个刚初始化的模型,所有参数都是随机数。问它 "Thank you very" 后面是什么?完全瞎猜——50257 个 token 概率差不多。训练之后呢?99.2% 的概率输出 "much"。从随机到精准,中间发生了什么? ▍一、先说结论 一句话版本:训练 = 喂数据 → 预测 → 算误差 → 调参数 → 重复几万亿次。▍二、训练的核心循环想象你在调一台有 70 亿个旋钮的收音机。目标是调到某个电台(让预测尽可能准),但你不知道每个旋钮该转到什么位置,只能靠试:随便拧 —— 给所有旋钮一个随机初始位置听一下 —— 用当前参数预测下一个词对答案 —— 看预测和真实文本差多远(算 Loss)微调旋钮 —— 每个旋钮稍微转一下,方向是让差距变小重复 —— 换下一段文本,再来一轮重复几万亿次。每次只调一点点,但积累下来,70 亿个旋钮就逐渐到了正确的位置。下面把每一步展开。 ▍三、Loss——“猜得有多离谱”模型输出 50257 个概率。训练时我们知道正确答案,所以可以量化"猜得有多差"——这个数叫 Loss(损失)。3.1 具体例子输入 "Thank you very",正确答案是 "much"。 随机初始化的模型 训练好的模型"much" 的概率: 1/50257 ≈ 0.002% 0.992 (99.2%)3.2 Loss 的计算公式Loss = -log(P(正确答案))代入数字:随机模型: Loss = -log(1/50257) = 10.8 ← 很大,猜得很离谱训练好的: Loss = -log(0.992) = 0.008 ← 接近 0,猜得很准为什么用负对数?两个好处:概率从 0 到 1,取负对数后变成 0 到正无穷——数值范围更适合做优化猜得越离谱(概率越小),Loss 越大,惩罚力度和"离谱程度"成正比你不需要记公式,只需记住:Loss 是一个数字,越小越好。训练的目标就是让它不断变小。 ▍四、梯度——“每个旋钮该往哪边转”知道了 Loss(猜得有多差),下一个问题是:70 亿个参数,每个该往哪个方向调?调多少?4.1 梯度是什么回到收音机。你现在 Loss 是 10.8(信号很差)。把某个旋钮稍微往右转一点点,听听 Loss 变了没:变成 8.3 → 往右转是对的,继续变成 8.7 → 方向反了,应该往左梯度就是这个信号:告诉每个参数"往哪个方向调"以及"调多大步"。 数学上,梯度是 Loss 对每个参数的偏导数。但不需要理解偏导数——只要知道它给出了方向和幅度。4.2 反向传播——从输出往回推模型的计算方向是:输入 → Embedding → Layer 1 → Layer 2 → ... → Layer 12 → 输出 → Loss梯度的计算方向是反过来的:Loss → 输出 → Layer 12 → ... → Layer 2 → Layer 1 → Embedding从 Loss 出发,通过链式法则,把"该怎么调"的信号一路传回每一层的每一个参数。这叫反向传播(Backpropagation)。就像多米诺骨牌倒着推——Loss 推倒最后一块,连锁反应一路传到第一块。每个参数都收到了自己该怎么调的信号。4.3 梯度下降——一步一步走下山有了梯度,就可以更新参数:新参数 = 旧参数 - 学习率 × 梯度学习率(learning rate) 是一个很小的数(比如 0.0001),控制每步走多远。太大会跨过最优解来回震荡,太小训练太慢。整个过程就像在一个 70 亿维的山谷里找最低点:梯度告诉你哪边是下坡,学习率决定每步多远,一步一步走,最终走到(接近)谷底——也就是 Loss 最小的地方。 ▍五、代码实验:亲手训练一个微型模型GPT-2 太大,没法在笔记本上训练。附件 train_tiny.py[1] 实现了一个微型 Transformer——2 层、4 个头、128 维,在 10 句话上训练,CPU 几分钟跑完。训练循环的核心只有四行,所有大模型的训练都是这四行:# 1. 前向传播:用当前参数做预测logits = model(x)# 2. 算 Loss:预测和正确答案差多远loss = F.cross_entropy(logits.view(-1, vocab_size), y.view(-1))# 3. 反向传播:算出每个参数的梯度(该往哪调)loss.backward()# 4. 更新参数:沿梯度方向微调一步optimizer.step()不管模型有 10 万参数还是 1 万亿参数,训练循环都是这四步。差别只在每一步的计算量。运行效果 Step 0: Loss = 83.250 (0.1s) Step 50: Loss = 2.395 (0.5s) ████████████ Step 100: Loss = 1.767 (0.8s) ████████████████ Step 150: Loss = 1.311 (1.0s) ████████████████████ Step 200: Loss = 0.976 (1.3s) ██████████████████████ Step 250: Loss = 0.834 (1.7s) ███████████████████████ Step 300: Loss = 0.527 (2.0s) ██████████████████████████ Step 350: Loss = 0.312 (2.3s) ███████████████████████████ Step 400: Loss = 0.263 (2.6s) ████████████████████████████ Step 450: Loss = 0.264 (2.8s) ████████████████████████████ Step 499: Loss = 0.219 (3.1s) ████████████████████████████训练后测试: 输入: 'The capital of ' → 输出: 'The capital of Italy is Rome.' ✓ 输入: 'Thank you very' → 输出: 'Thank you very much for your help.' ✓这说明了什么Loss 从 83.250 降到 0.219——模型从瞎猜变成了能续写训练数据中的句子。前 100 步下降最快(容易的规律先学到),后面越来越慢(难的规律需要更多迭代)。但它只是在"背课文"——我们只喂了 10 句话,模型记住了这 10 句话的模式。问它训练数据里没有的内容,它就会胡说。真正的大模型在几万亿个 token 上训练,覆盖了互联网上的海量文本。所以它"记住"的不是具体句子,而是语言的统计规律——语法结构、事实知识、推理模式。数据量的差异,决定了"背课文"和"学会语言"的区别。完整可运行代码见附件 train_tiny.py,纯 PyTorch 实现,不需要 transformers 库。* 本系列配套运行代码,可在公众号后台回复“大模型”完整获取。 ▍六、真实的大模型训练:三个阶段我们的微型模型只经历了一个阶段。真实的大模型要经过三个阶段,每个阶段解决不同的问题。6.1 预训练(Pre-training)——“广泛读书”目标:让模型学会语言——语法、知识、推理能力。数据:几万亿个 token 的互联网文本——网页、书籍、论文、代码、维基百科……任务:就是我们讲过的"预测下一个词"。把文本切成片段,每个位置预测下一个 token,算 Loss,调参数。规模感受:预训练完成后,模型已经能生成流畅的文本,知道大量事实,能做简单推理。但它有个问题:不会好好回答问题。你问它一个问题,它可能不回答,而是继续生成看起来像网页的内容——因为在训练数据里,一段文本后面跟的通常是另一段文本,不是"回答"。6.2 SFT(监督微调)——“入职培训”目标:教模型"好好回答问题"。数据:人工编写的高质量问答对,通常几万到几十万条:用户:法国的首都是哪里?助手:法国的首都是巴黎。巴黎位于法国北部...用户:写一个 Python 斐波那契函数助手:def fibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2)训练方式:和预训练完全一样——预测下一个 token,算 Loss,调参数。只是数据换成了对话格式,模型就学会了"看到问题后给出回答"的模式。SFT 的数据量比预训练小得多(几万条 vs 几万亿 token),但它让模型从"续写机器"变成了"能回答问题的助手"。6.3 RLHF(基于人类反馈的强化学习)——“师傅带徒弟”目标:让回答更符合人类偏好——更有帮助、更安全、更诚实。SFT 教模型"怎么回答",RLHF 教模型"什么样的回答更好"。分两步做:第一步:训练一个"打分模型"。同一个问题让模型生成两个回答 A 和 B,人类标注员选更好的那个。用大量这种偏好数据训练一个打分模型,让它能自动给回答打分。第二步:用打分模型优化语言模型。模型生成回答 → 打分模型打分 → 分数作为奖励信号 → 调整参数让模型倾向于生成高分回答。6.4 三阶段的效果变化预训练前: "jk2#x..." ← 随机噪声预训练后: "...the city is known for..." ← 流畅续写,但不会回答问题SFT 后: "巴黎是法国的首都。" ← 能回答了,但质量参差不齐RLHF 后: "法国的首都是巴黎。巴黎位于法国北部..." ← 回答详细、有帮助、安全▍七、训练的工程挑战原理不复杂,但真把一个 70B 模型训出来,工程上很难。7.1 显存装不下一个 7B 模型的训练需要多少显存?参数本身: 7B × 4 字节 = 28 GB 梯度: 同样大小 = 28 GB 优化器状态: Adam 需要额外存两份 = 56 GB 激活值: 中间计算结果 = 数十 GB ────────────────────────────── 总计: 远超 100 GB一张 A100 GPU 有 80 GB 显存,连参数和优化器都装不下——一张卡根本没法训 7B 模型。解决办法是分布式训练:把模型切成几块,分到不同的 GPU 上,几千张 GPU 通过高速网络协同工作。这就是为什么训大模型要花数百万美元——大部分是算力成本。7.2 数据质量比数据数量更重要训练数据里如果充满错误信息、恶意内容或低质量文本,模型就会学到这些"坏习惯"。所以训练前要做大量清洗:去重(互联网上到处是重复内容)、过滤垃圾页面、去除隐私信息、平衡语言和领域的比例。数据配比(多少英文、多少中文、多少代码、多少数学)是各家模型团队的核心秘方。 ▍八、训练改变了什么回顾前五篇,训练到底改变了哪些东西:Embedding 表(第三篇):训练前是随机数。训练后,"France" 和 "Paris" 的向量变得接近,"国王 - 男人 + 女人 ≈ 女王" 自动形成。Attention 的 Q/K/V 权重(第四篇):训练前,注意力分数是随机的,每个词对所有词的关注度差不多。训练后,"very" 学会了重点关注 "Thank you" 这个搭配。FFN 的权重(第五篇):训练前,FFN 做的是随机变换。训练后,FFN 学会了存储和调用知识——看到 "Thank you very" 就激活 "much"。所有这些变化,都来自同一个训练信号:预测下一个词。 没有人告诉模型 "France 的首都是 Paris",也没人告诉它 "Thank you very 后面接 much"。它只是在几万亿次预测中自动发现了这些规律,编码进了参数里。 ▍九、结语训练的本质简单得令人意外:预测 → 算误差 → 调参数 → 重复。复杂的不是算法,而是规模——70 亿个参数、几万亿个 token、数千张 GPU、数月时间。把一个简单过程推到极致的规模,涌现出了看起来像"理解语言"的能力。"Deep learning is just gradient descent on a loss function. Everything else is engineering."深度学习就是在 Loss 上做梯度下降。剩下的全是工程。下一篇,我们从训练切换到使用——你按下回车后的这一秒,模型内部发生了什么?为什么第一个字等得久、后面快了?KV Cache 是什么?本文配套代码:train_tiny.py(微型 Transformer 从零训练)。纯 PyTorch 实现,不需要 transformers 库,CPU 几分钟跑完。扫码回复“大模型”获取本系列文章完整配套代码「从零开始理解大模型」是「从零开始理解 Agent」的姊妹系列。Agent 系列讲"四肢",本系列讲"大脑"。建议对照阅读 专栏入口。
-
由Linux Foundation组织的LFX Mentorship计划[1],从2019年开始为CNCF各个开源社区中的开发人员持续提供带薪实习和指导。该项目往年已获2w+申请,发起2000+课题,毕业实习生1400+,发放超过380万美金报酬。LFX Mentorship 2026 夏季(Term 2)申请时间为5月5日 – 5月19日(11:00 PDT;18:00 UTC),远程实习将从 6 月 8 日开始为期三个月。参与到LFX Mentorship计划中,为开源项目做贡献、获得开源社区的认可同时,完成工作还能获取报酬 (位于中国的开发者报酬为3000美金,约合20000人民币)。Volcano社区在LFX Mentorship计划的课题申请正在火热进行中,感兴趣的开发者即日起可前往官方平台申请(在校/在职符合条件可):https://mentorship.lfx.linuxfoundation.org/ Volcano 社区介绍 Volcano 是 CNCF 首个批量计算项目,也是业界领先的云原生统一调度平台。Volcano 已从批量调度引擎演进为通智融合调度系统,面向 AI 训练、大模型推理、Agentic AI、大数据、基因测序等多样化工作负载提供统一的高性能调度能力,对 Spark、Flink、Ray、TensorFlow、PyTorch、Kubeflow、MPI、PaddlePaddle、MindSpore 等主流计算框架均有完善支持。社区在GitHub上已获得 6.5k+ Star 和 1.3K+ Fork,参与贡献企业包括华为、AWS、百度、腾讯、京东、小红书、bilibili 等。社区地址:🌋 https://github.com/volcano-sh在LFX Mentorship 2026夏季计划,Volcano期待与你协作开拓AI大数据、LLM大模型推理等场景调度的更多可能。 面 向 对 象 本期计划申请者需2026年5月19日前在LFX官网[1]完成Mentee注册及项目申请。若被接收作为Mentee,您将能在开源社区经验丰富、积极贡献的Mentor指导下为开源项目做出贡献。依据官方规定,对Mentee申请者有以下要求[2]:在参加该计划时您至少年满18周岁所在单位和组织不禁止该实习未参加另外的Linux Mentorship计划开发者以个人身份参与(在校或已毕业均可)具备所注册国家中工作权利且所注册国家未被计划禁止 (中国已获许可)满足具体所属项目中提及的其它前置需求 课题参与方式 根据官方安排 [3],LFX Mentorship 2026 年 Term2 申请及实习流程如下:Mentee注册与项目申请:5月5日-5月19日(11:00 AM PDT/18:00 UTC)申请者审核期: 5月20日-6月2日(11:00 AM PDT/18:00 UTC)申请者入选通知:6月3日实习正式开始:6月8日中期考核:7月21日(11:00 AM PDT/18:00 UTC)首次津贴支付:7月22日结项考核、实习报告提交:8月25日(11:00 AM PDT/18:00 UTC)最终津贴支付批准:8月26日本期结束最终日期:8月31参与者如有意向如何申请?流程详见 [4]:https://docs.linuxfoundation.org/lfx/mentorship/mentee-guide/how-to-apply实习申请结果预计将在6 月 3 日通知到申请人。主线开发日期为2026年6月8日-8月25日,全程线上协作,无需线下参与。结项需要在2026年8月25日前以 PR 的形式提交到项目所在的开源社区仓库中并完成合并。 Volcano 项目课题 欢迎各位申请者申报CNCF Volcano社区课题:▍支持 Namespace 级别的 Queue课题描述:Volcano 当前的 Queue 是集群级别的资源,只有集群管理员才有权限创建和修改。这在多租户场景下对普通租户不太友好:租户通常只拥有自己 namespace 下的权限,但也想用上 Queue 提供的能力(资源共享、capability/guarantee/deserved、队列层级等)来管理自己的作业,而不是每改一次都要依赖集群管理员。本课题会在 Volcano 中引入 namespace 级别的 NamespaceQueue。NamespaceQueue 从 cluster 级别的 Queue 派生,语义和使用方式与 cluster Queue 保持一致,租户可以直接在自己的 namespace 下创建和管理队列,并像使用 cluster Queue 一样把 PodGroup/Job 关联到 NamespaceQueue 上进行调度。对不使用这个特性的用户,原有 cluster Queue 的行为和 API 完全不受影响。预期产出:新增 namespace 级别的 NamespaceQueue CRD,从 cluster 级别的 Queue 派生,capability/guarantee/deserved、队列层级等字段语义保持一致租户不需要集群管理员权限,就能在自己 namespace 下创建和管理 NamespaceQueuePodGroup/Job 支持引用 NamespaceQueue,调度行为与引用 cluster Queue 一致NamespaceQueue 的资源统计、status、事件等能够正常工作与原有 cluster Queue 和 scheduling.volcano.sh/queue-name annotation 兼容,老用户可以平滑迁移覆盖核心流程和异常场景的 E2E 测试Volcano 官网和代码仓库的用户文前置技能:GoKubernetes(CRD、controller、RBAC)熟悉 Volcano(scheduler、queue、PodGroup/Job 等)E2E 测试(Ginkgo)GitHub workflow 与 shell 脚课题导师:Zicong Chen(@JesseStutler )jessestutler97@gmail.comHajnal Máté (@hajnalmt)hajnalmt@gmail.comJoão Azevedo (@devzizu)jazevedo960@gmail.com原始Issue:cid:link_2/issues/5251课题申请入口:https://mentorship.lfx.linuxfoundation.org/project/9e582ac4-4e12-4fcc-a1cd-27855d79730a▍Kthena Router 支持第三方模型 API课题描述:目前 Volcano/Kthena Router 已经能够很好地支持集群内部的路由能力。但在与用户的交流中,部分用户提出希望能够对接外部的大语言模型 API。因此,Kthena 社区计划借助本期 LFX,让 Router 具备访问第三方 LLM API 的能力。预期结果:设计提案(Proposal)代码实现(包含单元测试;如能补充端到端测试更佳。但考虑到外部 LLM API 通常不会提供长期、稳定的免费访问,端到端测试不作为强制要求)用户指南及相关文前置技能:Go、Kubernetes、网络、LLM课题导师:Zengzeng Yao(@yaozengzeng )yaozengzeng@huawei.com原始Issue:cid:link_3/issues/939课题申请入口:https://mentorship.lfx.linuxfoundation.org/project/baa6fb1f-58c9-4255-849c-21aca35ce5e1▍Kthena Router 性能基准测试(Benchmark)课题描述:Kthena Router 是 Volcano/Kthena 项目中的 LLM 路由组件,负责将推理请求转发到集群内(以及即将支持的)第三方模型后端。随着 Kthena 逐步走向成熟,社区需要一套可复现的基准测试,用来在真实的 LLM 流量模式下衡量 Router 的性能特征(吞吐、延迟、TTFT、资源占用),并在版本迭代中及时发现性能回退。本项目希望设计并实现一套面向 Kthena Router 的基准测试框架,产出完整的测试报告。如果在过程中发现明显的瓶颈或可优化点,还需要与 Maintainer 协作,将代码层面的优化合入上游。预期产出:一套可复用的 Kthena Router 基准测试框架(压测客户端、场景配置、指标采集、结果汇总),可在本地乃至 CI 中运行。一组覆盖典型 LLM 路由模式的测试场景(不同的 QPS、prompt/response 长度、并发数、后端数量、路由策略等)。端到端测试流程文档化为 runbook(集群准备、mock/真实后端、运行方式、结果解读)。一份基准测试报告,包含吞吐、TPOT、TTFT、GPU/CPU/内存等指标,以及瓶颈分析。针对识别到的明显瓶颈进行优化并提交上游 PR,附上优化前后的性能对比数据前置技能:Go、Kubernetes、性能基准测试与性能剖析(pprof)、对 LLM 推理及 HTTP/gRPC 路由有基本了解。课题导师:Zengzeng Yao(@yaozengzeng )yaozengzeng@huawei.comZhonghu Xu (@hzxuzhonghu )zhhxu2011@gmail.com原始Issue:cid:link_3/issues/942课题申请入口:https://mentorship.lfx.linuxfoundation.org/project/1cf34cb5-3520-4f15-81c8-4258cb9abcb9▍支持多 AgentCube 协同能力课题描述:目前, Volcano社区AgentCube项目 在 Code Interpretation和 Agent Runtime场景下都只会拉起单个 Agent。然而,当前我们已经进入多 Agent 协作的时代。因此,AgentCube 计划支持多 Agent 编排,使多个 Agent 能够围绕同一个任务进行协作,并由 AgentCube 统一管理这些 Agent 的生命周期。预期结果:设计提案(Proposal)代码实现(包含单元测试和端到端测试)用户指南及其他相关文前置技能:Go、Kubernetes、Agent课题导师:Zhonghu Xu (@hzxuzhonghu )zhhxu2011@gmail.com原始Issue:cid:link_1/issues/301课题申请入口:https://mentorship.lfx.linuxfoundation.org/project/9e7dd1c1-5d14-4c5e-af43-83454099e490更多Volcano课题,请访问LFX Mentorship官网[1];对课题感兴趣/有任何问题,欢迎直接向课题导师发送邮件或在GitHub仓库提交Issue提问。今年夏季,Volcano社区期待在 LFX Mentorship 见到您! 附:相关指引链接[1] LFX Mentorship计划官网及申报入口: https://mentorship.lfx.linuxfoundation.org/#projects_all[2] LFX Mentorship - Application Requirement: https://docs.linuxfoundation.org/lfx/mentorship/mentee-guide/am-i-eligible[3] LFX Mentorship - Program Readme: cid:link_0[4] LFX Mentorship - Mentee Application Guideline: https://docs.linuxfoundation.org/lfx/mentorship/mentee-guide/how-to-apply[5] Volcano GitHub: cid:link_2[6] Volcano/Kthena GitHub: cid:link_3[7] Volcano/AgentCube GitHub: cid:link_1 关注魔方公众号,获取更多前沿资讯添加社区小助手k8s2222,进入Volcano技术交流群
-
一、背景介绍在大模型推理部署中,Prefill-Decode(P/D)分离是一种被广泛采用的性能优化架构。随着大语言模型参数量不断增长,推理过程中的计算资源消耗和延迟问题日益突出。传统的一体化推理架构难以同时优化首token延迟(TTFT)和整体吞吐率(TPOT),而P/D分离通过将推理过程拆分为两个独立阶段,让每个阶段使用最适合其计算特性的并行策略,实现了显著的性能提升。本文将详细介绍如何通过Kthena控制器,在昇腾NPU上部署DeepSeek-V4-Flash模型,完成P/D分离的实践。我们会深入解析P/D分离的技术原理、Kthena的编排能力,以及ModelRoute如何实现P/D实例的自动发现与KV传输协作。相关部署模板参考Kthena项目地址:cid:link_0 二、P/D分离技术原理2.1 大模型推理的两阶段解析大语言模型的推理过程是一个自回归生成过程,本质上分为两个截然不同的阶段:Prefill阶段(首token生成)Prefill阶段负责处理用户输入的prompt,将完整的输入序列通过模型前向传播,生成第一个输出token。这个阶段具有以下特征:计算密集型:需要处理整个输入序列,每个token都需要与所有输入token进行注意力计算并行度高:输入序列的所有位置可以并行计算,适合较大的张量并行(TP)规模内存访问模式:KV Cache首次生成,需要写入到高速缓存中延迟敏感:用户等待首token的时间直接影响体验在我们的配置中,Prefill阶段采用DP(数据并行)=2、TP(张量并行)=8的配置,利用更大的张量并行度来加速矩阵运算:--data-parallel-size 2 \--tensor-parallel-size 8 \--max-num-batched-tokens 8192 \--max-num-seqs 4 \Decode阶段(增量生成)Decode阶段是自回归生成过程,每次只处理一个新生成的token,并将其加入序列进行下一轮推理。这个阶段的特点与Prefill截然不同:Memory-Bound型:每次只计算一个token,但需要读取完整的KV Cache并行度需求低:单个token的计算量有限,过大的张量并行反而增加通信开销吞吐率敏感:需要最大化单位时间内生成的token数量KV传输频繁:每个Decode实例都需要访问所有Prefill实例生成的KV CacheDecode阶段采用DP(数据并行)=8、TP(张量并行)=2的配置,通过更大的数据并行来提升整体吞吐:--data-parallel-size 8 \--tensor-parallel-size 2 \--max-num-batched-tokens 144 \--max-num-seqs 48 \2.2 为什么P/D分离能提升性能传统的单体架构面临"一刀切"的困境:为了同时满足Prefill和Decode的需求,必须在并行策略上做出妥协,导致两个阶段都无法达到最优。而P/D分离的核心价值在于解耦:维度单体架构P/D分离张量并行折中值(如TP=4)Prefill用TP=8,Decode用TP=2数据并行固定值各角色独立扩展资源配置统一规格按需分配扩缩容整体调整独立扩缩容以DeepSeek V4为例:Prefill优化:更大的TP size(8)加速注意力计算,更大的批处理量(8192 tokens)提升吞吐Decode优化:更大的DP size(8)支持更多并发序列,更小的TP size(2)减少通信开销2.3 KV Cache传输机制P/D分离后,Prefill和Decode之间需要高效传输KV Cache,这是P/D分离架构中最关键的技术挑战之一。在我们的部署中,使用Mooncake Connector V1实现KV传输:--kv-transfer-config\'{"kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", # Prefill为producer "kv_port": "9000", "engine_id": "$MOONCAKE_ENGINE_ID", ...}'Mooncake KV传输原理:Producer端(Prefill):生成的KV Cache通过Mooncake引擎传输到Decode节点Consumer端(Decode):从Mooncake引擎拉取KV Cache用于注意力计算Engine ID:每个P/D实例组有唯一的engine ID(${GROUP_NAME}_${ROLE_ID}),确保数据传输到正确的目标# Prefill配置"kv_role":"kv_producer"# Decode配置"kv_role":"kv_consumer"Mooncake具备昇腾NPU优化的高性能通信库,能够实现节点间KV Cache的低延迟传输,是P/D分离能够实际落地的关键技术。三、为什么P/D分离需要适配的Router3.1 路由在P/D分离架构中的核心作用在P/D分离架构中,请求的路由不再是简单地分发到某个后端实例,而是需要智能地协调Prefill和Decode两个阶段,这与传统微服务路由有本质区别。传统微服务路由:Client Request → Router → Backend Instance (处理完整请求)P/D分离路由:Client Request → Router → Prefill Instance (生成首token) ↕ (KV传输) Decode Instance (完成剩余生成)3.2 路由需要解决的挑战挑战一:请求生命周期管理一个完整的请求在P/D架构中需要经过多个阶段:请求首先路由到Prefill处理Prefill生成首token后,需要将请求转交给DecodeDecode可能需要多轮生成,每轮都涉及KV传输最终结果需要汇总返回给用户这要求Router必须理解P/D的请求流程,而不仅仅是做简单的负载均衡。挑战二:P/D实例发现与匹配Prefill和Decode实例数量可能不同(1P2D、2P1D等)请求需要在正确的Prefill和Decode实例之间传递需要跟踪每个请求当前由哪个实例处理挑战三:KV传输的协调KV Cache的传输需要满足以下条件:Prefill生成的KV必须传输到处理该请求的Decode实例Mooncake的engine_id需要正确配置以匹配P/D实例传输超时和错误处理挑战四:流量分配策略不同场景下可能需要不同的P/D配比:计算密集型场景:增加Prefill副本IO密集型场景:增加Decode副本Router需要支持动态调整流量分配3.3 ModelRoute的适配设计Kthena的ModelRoute正是为解决上述挑战而设计的适配层。它不仅负责基本的请求路由,还需要理解P/D分离的语义,协调Prefill和Decode的协作。四、ModelRoute配置详解4.1 整体配置结构apiVersion:networking.serving.volcano.sh/v1alpha1kind:ModelRoutemetadata:name:deepseek-v4namespace:defaultspec:modelName:"deepseek_v4"rules:-name:"default" targetModels: -modelServerName:"deepseekv4-pd"---apiVersion:networking.serving.volcano.sh/v1alpha1kind:ModelServermetadata:name:deepseekv4-pdnamespace:defaultspec:inferenceEngine:vLLMmodel:"deepseek_v4"workloadPort: port:7100 protocol:httpworkloadSelector: # 工作负载选择器 matchLabels: modelserving.volcano.sh/name:deepseekv4-pd # 这是最基本的标签匹配,用于识别属于该服务的所有Pod。 pdGroup: # P/D分组配置 groupKey:"modelserving.volcano.sh/group-name"# 指定用于分组的标签key prefillLabels: # 标记哪些Pod是Prefill角色 modelserving.volcano.sh/role:prefill decodeLabels: # 标记哪些Pod是Decode角色 modelserving.volcano.sh/role:decodetrafficPolicy: timeout:"300s" retry: attempts:3 retryInterval:"150ms"kvConnector: type:mooncake其中P/D分组配置(pdGroup)是实现P/D识别的关键配置:groupKey:指定用于分组的标签key,具有相同groupKey值的Pod属于同一个P/D实例组。这解决了一个关键问题:当我们部署多个P/D实例组时(如2×(1P1D)),Router需要知道哪些Prefill和Decode属于同一个组。prefillLabels:标记哪些Pod是Prefill角色。decodeLabels:标记哪些Pod是Decode角色。4.2 实例发现的实现机制Kthena控制器通过以下步骤实现P/D实例的自动发现:步骤1:标签注入在deepseek-serv.yaml中定义的ModelServing资源会被Kthena控制器处理,自动为每个Pod注入标签:metadata: labels: modelserving.volcano.sh/name:deepseekv4-pd modelserving.volcano.sh/group-name:<group-id> # 自动生成 modelserving.volcano.sh/role:prefill/decode # 根据role名称 modelserving.volcano.sh/role-id:<role-id> # 自动生成步骤2:标签查询ModelRoute的pdGroup配置会被控制器用于查询匹配的Pod:1. 查询所有 labels[modelserving.volcano.sh/name] = deepseekv4-pd 的Pod2. 按 labels[modelserving.volcano.sh/group-name] 分组3. 在每个组内,识别prefillLabels和decodeLabels匹配的Pod步骤3:动态维护当发生扩缩容时:新Pod创建后自动获得标签Router实时感知Pod变化无需手动更新配置4.3 KV传输的协调ModelRoute通过以下配置协调KV传输:kvConnector: type:mooncakeMooncake Connector的工作流程:1️⃣ Prefill启动时:从环境变量获取GROUP_NAME和ROLE_ID构建engine_id = ${GROUP_NAME}_${ROLE_ID}启动Mooncake Server,监听KV请求2️⃣ Decode启动时:使用相同的GROUP_NAME但不同的ROLE_ID配置为kv_consumer角色通过engine_id连接到对应Prefill的Mooncake Server3️⃣ 请求处理时:Prefill处理用户输入,生成KV CacheKV Cache通过Mooncake传输到对应Decode实例Decode使用接收到的KV继续生成4.4 流量策略配置trafficPolicy: timeout:"300s" retry: attempts:3 retryInterval:"150ms"这些配置确保了请求在P/D之间的可靠传递:timeout:整个生成过程可能需要较长时间,设置5分钟超时retry:如果请求在Prefill或Decode环节失败,自动重试五、Kthena编排的核心优势5.1 声明式编排简化运维传统方式下,部署P/D分离架构需要:手动创建和管理多组Deployment/Service手动配置Service之间的发现机制手动管理标签选择器和Endpoints使用Kthena的ModelServing,仅需声明式配置:apiVersion:workload.serving.volcano.sh/v1alpha1kind:ModelServingmetadata:name:deepseekv4-pdspec:replicas:1template: roles: -name:prefill replicas:1 -name:decode replicas:1控制器会自动完成:创建和管理Prefill/Decode的Pod注入必要的标签(group-name、role、role-id)设置健康检查配置资源限制5.2 灵活的P/D比例调整单实例1P1D:roles:-name:prefill replicas:1-name:decode replicas:1调整为2P1D(提升Prefill吞吐):roles:-name:prefill replicas:2 # 从1改为2-name:decode replicas:1调整为1P2D(提升Decode吞吐):roles:-name:prefill replicas:1-name:decode replicas:2 # 从1改为2部署2组独立的1P1D实例(横向扩展):spec: replicas:2 # 整体副本数设为2,每组自动生成1P1D我们测试了以下几种灵活的P/D比例配置:部署模式Prefill replicasDecode replicas说明1P1D11基础配置2P1D21提升Prefill吞吐,适合输入长度较大的场景1P2D12提升Decode吞吐,适合输出长度较大的场景2×(1P1D)2组P/D实例2组P/D实例横向扩展,整体吞吐翻倍所有这些调整都只需修改yaml配置并执行:kubectl apply -f deepseek-serv.yamlKthena控制器会自动处理Pod的创建、销毁和负载均衡。5.3 自动服务发现在传统的P/D部署中,需要手动配置服务发现:Prefill服务需要知道所有Decode实例的地址Decode服务需要知道所有Prefill实例的地址扩缩容时需要手动更新配置Kthena通过pdGroup和标签机制实现了自动服务发现:新增的Prefill或Decode实例自动被Router识别使用相同的group-key的实例自动组成P/D组无需手动配置实例地址六、部署实践6.1 模型准备为了加速部署和启动过程,我们将DeepSeek-V4-Flash模型权重预先下载到所有计算节点的 /models/DeepSeek-V4-Flash-w8a8-mtp 目录下。该目录应包含完整的模型权重文件、配置文件以及chat_template.jinja模板文件。从ModelScope下载模型权重:# 安装ModelScopepip install modelscope# 下载DeepSeek V4 Flash模型modelscope download --model Eco-Tech/DeepSeek-V4-Flash-w8a8-mtp --local_dir /models/DeepSeek-V4-Flash-w8a8-mtp如果使用git-lfs进行大文件管理,也可以:# 安装git-lfsgit lfs install# 克隆模型仓库GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/Eco-Tech/DeepSeek-V4-Flash-w8a8-mtp.git /models/DeepSeek-V4-Flash-w8a8-mtp# 进入目录并下载LFS大文件cd /models/DeepSeek-V4-Flash-w8a8-mtpgit lfs pull注意事项:确保所有计算节点的模型目录路径一致(/models/DeepSeek-V4-Flash-w8a8-mtp)可以在共享存储(如NFS)上预先下载模型,然后挂载到各个节点模型下载完成后,建议验证文件完整性:ls -la /models/DeepSeek-V4-Flash-w8a8-mtp/# 应包含 config.json, model.safetensors, chat_template.jinja 等文件6.2 完整部署流程Step 1: 创建ConfigMap(包含启动脚本)kubectl apply -f config.yamlconfig.yaml定义了Prefill和Decode的启动脚本,包含:环境变量配置vLLM启动参数Mooncake KV连接配置Step 2: 部署ModelServingkubectl apply -f deepseek-serv.yaml创建完整的P/D分离实例,包括:Prefill实例(1副本)Decode实例(1副本)自动注入的标签和配置Step 3: 配置路由kubectl apply -f modelRoute.yaml创建ModelRoute和ModelServer两个对象:ModelRoute:定义路由规则ModelServer:定义后端服务6.2 验证部署# 查看ModelServing状态kubectl get modelserving deepseekv4-pd# 查看所有相关Podkubectl get pods -l modelserving.volcano.sh/name=deepseekv4-pd# 查看Pod详情(确认标签)kubectl get pods -l modelserving.volcano.sh/name=deepseekv4-pd -o wide# 检查Pod日志kubectl logs -l modelserving.volcano.sh/role=prefillkubectl logs -l modelserving.volcano.sh/role=decode6.3 扩缩容操作扩缩容Prefill:# 编辑配置kubectl edit modelserving deepseekv4-pd# 将 prefill.replicas 从 1 改为 2# 或者使用patchkubectl patch modelserving deepseekv4-pd --type='json' \ -p='[{"op": "replace", "path": "/spec/template/roles/0/replicas", "value": 2}]'扩缩容Decode:kubectl patch modelserving deepseekv4-pd --type='json' \ -p='[{"op": "replace", "path": "/spec/template/roles/1/replicas", "value": 2}]'七、总结通过本次实践,我们验证了 Kthena 在昇腾 NPU 环境下部署 DeepSeek-V4-Flash 模型 P/D 分离(Prefill/Decode Disaggregation) 架构的完整可行性。主要成果:成功实现P/D分离部署,Prefill和Decode独立运行通过Mooncake KV传输实现P/D协作支持灵活的P/D比例调整(1P1D、2P1D、1P2D等)支持多实例横向扩展Kthena的核心价值:简易性:声明式配置替代复杂的手动编排,控制器自动处理Pod管理和标签注入灵活性:通过replicas字段即可独立调整P/D比例,无需修改其他配置自动发现:pdGroup机制实现P/D实例的自动识别和配对KV协调:与Mooncake深度集成,确保KV传输的正确路由综上所述,P/D 分离是提升大模型分布式推理效能的核心技术路径,而 Kthena 的适配 Router 设计与编排逻辑,为这一复杂架构在生产环境中的标准化部署提供了确定性的方案,确保了大模型服务在昇腾算力底座上的高效稳定运行。 相关部署模板参考Kthena项目地址:cid:link_0Kthena GitHub地址:cid:link_1 更多信息,欢迎访问 Kthena 官网: https://kthena.volcano.sh/欢迎Star★,Fork,来 Kthena 社区一起玩转LLM推理! 扫码回复“Kthena” 进入技术群
-
Kthena 是一个专为 Kubernetes 设计的云原生、高性能 LLM 推理路由和编排、调度系统。它旨在解决在生产环境中大规模编排、部署和服务 LLM 所面临的核心挑战,通过其独特的超节点拓扑感知的亲和性调度,KV Cache 感知的流量调度、Prefill/Decode 分离路由等高级功能,显著提升 GPU/NPU 资源利用率和吞吐,降低推理延迟,赋予企业前所未有的灵活性和控制力。作为 Volcano[1] 的子项目,Kthena [2] 致力于扩展 AI 训练之外的边界,打造训推一体的完整解决方案。Kthena 最新发布的 Kthena v0.4.0[3] 版本进一步简化了大语言模型(LLM)工作负载的管理,为 AI 基础设施赋能。该版本源于社区贡献者在过去两个月中的倾力付出与通力合作,运行更加稳定,功能更加丰富。 Kthena v0.4.0 关键特性 ▍更快、更智能的路由器 (Router)确定且高效的模型选择此前,由于 Kubernetes 内置的 CRD 校验无法强制实现跨对象的全局唯一性,将多个 ModelRoute 资源映射到同一个模型时可能会引发路由冲突,导致规则匹配出现歧义和目标选择的不一致。在Kthena v0.4.0,我们优雅地解决了这一问题。Kthena v0.4.0 引入了可靠的冲突解决机制[4]。当存在重复的 ModelRoute 时,路由器会确定性地优先选择最早创建(通常是预建)的路由,并将较新的重复项视为较低优先级。这确保了每次路由请求都能获得可预测且稳定的结果。可配置的Prefix-Cache统一的标准往往无法满足所有场景的需求。因此,Kthena 将硬编码的Prefix-Cache参数替换成了完全可配置的Prefix-Cache系统[5]。您现在可以通过以下参数对Prefix-Cache的行为进行细粒度的控制:Block Size(哈希处理块大小): 控制前缀匹配的粒度。较小的块能够提供更精确的匹配,但会增加 CPU 开销;而较大的块处理速度更快,但精准度会下降。Max Block Limits(最大块限制): 设定了对给定提示词(prompt)进行哈希处理的上限。避免路由器在处理过长的传入提示词时,出现延迟激增。Cache Capacity(缓存容量): 定义了路由器可以记住的前缀条目数量。增加此值可以提高多样化工作负载的缓存命中率,代价是略微增加内存占用。Top-K Results(Top-K 结果数): 决定在匹配成功时考虑多少个候选实例。调整此参数有助于实现更好的负载均衡,确保流量平稳地分布在多个节点上,而不是让单个活跃实例过载。通过微调这些设置,您可以定制 Kthena Router的Prefix-Cache,以更好地适配多样的模型和业务 LLM 工作负载。▍细粒度、资源高效的滚动更新过去,Kthena 能在整个 ServingGroup 级别执行滚动更新。但对于大规模的大型语言模型应用而言,完全重建一个 ServingGroup 往往是一个极其消耗资源且耗时的过程。为了解决这个问题,我们引入了基于 Role 的滚动更新机制[6]。当只有特定的 Role 需要变更时,您无需再更新整个 ServingGroup(这也是我们在恢复策略中引入 RoleRecreate 的原因)。从 v0.4.0 开始,可以动态调整 rolloutStrategy——这将大幅降低升级时的资源消耗,并显著缩短升级时ServingGroup的不可用时间。▍支持SGLang和vLLM的PD分离部署PD 分离部署架构已经成为了大规模 LLM 服务的标准架构。在 Kthena v0.4.0 中,Kthena 的modelServing和Router现已通过全面验证,能够良好地支持 vLLM 和 SGLang 的PD分离部署。用户可以根据需求通过 ModelServing 配置 Prefill 和 Decode。并结合 ModelServer 中的 pdGroup 配置实现 PD 感知的智能路由,从而轻松构建高效的 PD 分离推理服务。▍提升可观测性Role 状态可见性为了最大限度地降低 kube-apiserver 的负载,Kthena 的 ModelServing 使用了本地存储缓存 ServingGroup 和 Role 的状态。虽然这种方式效率很高,但我们也意识到,这限制了 Kthena 的可观测性,使整个 reconcile 过程中ServingGroup和Role的状态变化变成了一个黑盒,无法观测。在 v0.4.0 中,我们打破了这种“黑盒”状态。现在,我们能够直接通过 Kubernetes Events 暴露 Role 的状态[7],从而显著提升了 ModelServing 的可观测性。在未来的规划中,我们还计划根据用户需求将关键的 Role 信息直接嵌入到 ModelServing 的 Status 中,为您提供全面且透明的部署状态掌控能力。为开发者提供debug-port,可以直接拉取本地缓存中的ServingGroup和Role的状态。全面的访问日志现在,Router 会生成更详细的访问日志,为每一个请求捕获更丰富多样的路由元数据 (routing metadata)[8]。以下是 Kthena v0.4.0 Router 日志的一个示例:[2026-04-16T07:33:08.435627146Z] "POST /v1/chat/completions HTTP/1.1" 200 model_name=deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B model_router=deepseek-r1-1-1.5b model_server=deepseek-r1 selected_pod=deepseek-r1-1-1.5b-6989c66877-p6jvv request_id=ad683d1b-6011-4b0f-b9b5-cbb18d43c57b gateway=dev/default http_route=kthena-e2e-gie-8eoas/llm-route inference_pool=kthena-e2e-gie-8eoas/deepseek-r1-1-1.5b tokens=10/38 timings=3ms(0+2+0)与之前的版本相比,我们新增了 gateway、http_route 和 inference_pool 字段,以便对 Gateway 及 Gateway Inference Extension 的流量提供丰富的信息。▍开放的生态系统Kthena 致力于与广大的开源社区一道,将社区建设成为一个开放、包容且繁荣的项目。支持 ModelScope (魔搭社区)在 v0.4.0 中,Kthena 的模型下载器中扩展了对 ModelScope 协议的支持[9]。这使得用户和运维管理人员可以更加灵活地选择符合其项目需求的模型仓库。Kthena 拒绝绑定单一技术栈,而是坚持与多样化的 AI 技术无缝集成,从而不断深耕于充满活力的云原生 AI 生态之中。社区热忱地邀请全球开发者加入,共同构建包容且充满机遇的未来数字基础设施。 Kthena v0.4.0 贡献者 @YaoZengzeng@VanderChen@hzxuzhonghu@Tweakzx@pierluigilenoci@lihua871205@nalan2012@Murphylu1993@xrwang8@thisisharsh7@vyagh@FAUST-BENCHOU@LiZhenCheng9527@aabhinavvvvvvv@anirudh240@blenbot@sicaario@katara-Jayprakash@WHOIM1205@agrawalcodes 相关链接[1] Volcano: https://volcano.sh/[2] Kthena : https://kthena.volcano.sh/[3] Kthena v0.4.0: cid:link_0[4] 冲突解决机制: cid:link_1[5] 可配置的Prefix-Cache系统: cid:link_2[6] 基于 Role 的滚动更新机制: cid:link_3[7] 直接通过 Kubernetes Events 暴露 Role 的状态: cid:link_4[8] 路由元数据 (routing metadata): cid:link_5[9] ModelScope 协议的支持: cid:link_6 扫码回复“Kthena” 进入技术群
-
欢迎阅读「从零开始理解大模型」系列 —— 十篇文章,从"下一个词预测"到完整的大模型心智模型。每篇配可运行代码。第一篇:一切从"猜下一个词"开始第二篇:Token——大模型眼中的"字"长什么样第三篇:向量与 Embedding——把文字变成数学第四篇:Attention——大模型的"阅读理解"机制第五篇:Transformer 全景——积木怎么搭成大厦第六篇:训练——70 亿个参数是怎么"学"出来的第七篇:推理——你按下回车后的这一秒发生了什么第八篇:上下文窗口——大模型的"工作记忆"第九篇:Scaling Law——为什么"大力出奇迹"有效第十篇:从大模型到 Agent——下一个词预测如何长出手脚作者:十一前四篇,我们一块一块地认识了积木:Token(第二篇)—— 把文字切成模型认识的碎片Embedding(第三篇)—— 把碎片变成带语义的向量Attention(第四篇)—— 让每个词"看见"上下文但光有积木还不够。Attention 只是 Transformer 一层的一半,另一半是什么?GPT-2 有 12 层,LLaMA 有 32 层,为什么要叠这么多?这篇把积木搭成完整的大厦。读完之后,大模型从输入到输出的每一步,你都明白了。 ▍一、先说结论一句话版本:Transformer = (Attention + FFN) × N 层,再加点"胶水"。就这么简单的结构,重复 N 次,就是所有大模型的骨架。 ▍二、先打个比方,建立全局感觉想象一家公司,一份报告要经过 12 个部门审阅。每个部门固定做两件事:开会(Attention)—— 大家坐在一起,互相交流信息。每个人听完别人的发言,更新自己的理解。"你们都说说,我综合一下。"回工位写总结(FFN)—— 开完会,每个人回去独自思考,把讨论内容消化成自己的判断。"我自己想想,这事到底意味着什么。"另外有两个保障机制:保留原件(残差连接)—— 每次修改,都在原件上叠加,不会覆盖原件。"改归改,原来的东西不能丢。"统一格式(LayerNorm)—— 每次流转前,把报告里的数字拉到统一范围。"大家别一个写米、一个写公里,先统一度量衡。"12 个部门审完,报告里既有所有部门的意见,又没丢失原始信息。这就是 Transformer 干的全部事情。 下面一个一个展开。 ▍三、一层 Transformer 长什么样画成流程图:输入向量 │ ▼┌─────────────────────────────────────┐│ ① LayerNorm(统一格式) ││ ② Multi-Head Attention(开会) ││ ③ 残差连接:输出 = 输入 + 开会结果 │├─────────────────────────────────────┤│ ④ LayerNorm(统一格式) ││ ⑤ FFN(独立思考) ││ ⑥ 残差连接:输出 = 输入 + 思考结果 │└─────────────────────────────────────┘ │ ▼输出向量(送去下一层继续处理)上半部分是 Attention——让词和词之间互相交流。下半部分是 FFN——让每个词自己消化信息。中间的 LayerNorm 和残差连接做稳定保障。写成代码,核心就四行:residual = hiddenhidden = residual + attention(layernorm_1(hidden)) # 开会 + 保留原件residual = hiddenhidden = residual + ffn(layernorm_2(hidden)) # 独立思考 + 保留原件看着是不是特别朴素?别小看它——GPT-4、Claude、LLaMA、DeepSeek,内部全是这四行在不断重复。下面逐个讲解三个你还没见过的新组件。 ▍四、FFN——"开完会了,自己坐下来想一想"4.1 光开会还不够第四篇讲的 Attention,让每个词都"听到了"其他词的信息。处理 "Thank you very" 的时候,"very" 知道了前面有 "Thank" 和 "you"。但"听到"不等于"想明白"。就像你参加了一场会,听了一大堆发言,脑子里全是信息碎片。你还得回到工位上坐下来,自己理一理:**"这些信息综合起来,到底说明什么?"**这个"坐下来理一理"的步骤,就是 FFN(Feed-Forward Network,前馈网络)。为什么叫"前馈"?因为数据只往前走,不回头——当前 token 的信息处理完后,直接"喂"给下一层,不会把自己的输出再喂回自己。没有循环、没有反复,一路向前。4.2 它到底怎么做的公式长这样:FFN(x) = W₂ · GELU(W₁ · x + b₁) + b₂这里的 W₁、W₂ 是训练时学出来的权重矩阵,训练完就固定不变了。同一层里所有 token 共用同一组 W₁、W₂——不是每个 token 各有一份。别被公式吓着。拆开来看就是三步:输入(768 个数字) │ ▼ 第一步:"展开"—— 乘一个大矩阵,768 维变成 3072 维 │ 就好比把一页笔记铺开到四页纸上,有更多空间做标注 │ ▼ 第二步:"划重点"—— 用激活函数(GELU)过一遍 │ 就好比拿一支半透明荧光笔划重点: │ - 特别重要的内容(正数)会被高亮保留 │ - 不太重要的内容(负数)也不会被完全涂黑,而是被轻轻压低、保留一点点痕迹 │ ▼ 第三步:"压缩"—— 再乘一个大矩阵,3072 维压回 768 维 │ 就好比把四页标注总结回一页精华 │ ▼ 输出(还是 768 个数字)有一个特别重要的特点:FFN 只看自己,不看别人。 "very" 做 FFN 的时候,完全不管 "Thank" 和 "you" 在干嘛。这和 Attention 正好反过来——Attention 是"大家一起交流",FFN 是"每个人独自思考"。4.3 为什么说 FFN 是"知识库"有一个有趣的发现:大模型记住的事实(比如"法国首都是巴黎")主要存在 FFN 的权重里。打个比方:Attention 是搜索引擎——在上下文里搜到了 "Thank you" 这个线索FFN 是大脑里的记忆——看到这个线索后,从记忆中调出 "much" 这个最强搭配一个负责找线索,一个负责给答案。两者配合,才能又找对又答对。 ▍五、残差连接——"改归改,原件必须留着"5.1 世界上最简单的操作输出 = 输入 + f(输入) // f 是 Attention 或 FFN就是把输入原封不动加到输出上。对,就这么简单。但为什么叫"残差"? 移项一下就明白了:f(输入) = 输出 - 输入 = 残差Attention 和 FFN 学到的东西,不是"完整答案该长啥样",而是"跟输入差多少"。这个差值就叫残差。学一个小的修正量,比从零学一个完整答案简单多了。这就是残差学习的核心思想,名字也从这来。5.2 没有它,12 层就废了想想"传话游戏":你悄悄告诉第一个人一句话,一个传一个,传 12 轮——最后一个人说出来的,跟原话八竿子打不着。没有残差连接的 Transformer 就是这样。12 层一叠,原始信息早就面目全非了。而且训练的时候,调参数的信号(叫"梯度")要从第 12 层一路传回第 1 层,每过一层就弱一点。传 12 层下来,信号几乎没了——前面的层调不动参数,就等于白训练。这个问题叫梯度消失,是深层网络最经典的老大难。5.3 加上它之后,画风完全不同残差连接等于给每一层装了一条直通管道:输入 ──────┬──────────────────────────────────┐ │ │ ▼ │ 直通管道 Attention/FFN 处理 │(原始信息直接穿过去) │ │ ▼ │ 修正量(Δ)───────→ (+) ◄────────────────┘ │ ▼ 输出 = 输入 + Δ不管 Attention/FFN 处理得多好或多烂,原始输入都通过直通管道完整到达了终点。所以每一层不需要"从零开始写一份新报告",只需要在原报告上批注几句修改意见:Layer 1 输出 = Embedding + Δ₁ ← 第一个部门批了几句Layer 2 输出 = Embedding + Δ₁ + Δ₂ ← 第二个部门又批了几句...Layer 12 输出 = Embedding + Δ₁ + ... + Δ₁₂ ← 12 个部门的修改意见叠在一起就像改文章——不是每一稿从头写,而是在上一稿基础上改红字。改 12 轮,肯定比从零写 12 遍容易得多。用 transformer_anatomy.py[1] 可以验证:即使经过 12 层变换,输出和原始 Embedding 的余弦相似度还是很高。原始信息确实通过直通管道保到了最后。 ▍六、LayerNorm——"每次传递前,先统一度量衡"6.1 为什么需要你去菜市场买菜,一个摊位标价"3",另一个标价"3000"。哪个贵?不知道——因为一个单位是"元/斤",另一个是"元/吨"。数字大小没意义,除非单位统一。Transformer 里也是这样。向量经过矩阵乘法和加法之后,有些维度的数字飙到 100,有些缩到 0.001。差了十万倍。后续的 Softmax 看到这种极端分布就懵了:它会把几乎全部注意力给最大的那个值,其他值全变成零。数字大小太离谱,后面的计算全带跑偏了。6.2 怎么解决LayerNorm 干的事特别朴素:把向量里所有数字"拉"回差不多大的范围。LayerNorm(x) = γ · (x - μ) / σ + β拆开来看:先算平均值(μ),把所有数字都减去平均值——让中心归零再算散开程度(σ),除以它——让大小统一最后乘以 γ 加上 β——留一点微调余地(γ 和 β 是训练时学出来的)看个具体例子:输入: [100.0, 0.001, -50.0, 25.0] ← 差距十万倍,后续计算会炸 ↓ 减均值 18.75,除标准差 55.9输出: [1.45, -0.34, -1.23, 0.11] ← 都在 -2 到 +2 之间了,好处理多了就像考试成绩——原始分可能是 150 分满分、也可能是 10 分满分,没法比。但转成"标准分"之后,所有人的成绩都在同一个尺度上了。LayerNorm 的参数很少——GPT-2 每层只有 3072 个——但缺了它模型就训不出来。真正的四两拨千斤。 ▍七、拆开 GPT-2,看参数都在哪四个组件都认识了。现在打开 GPT-2 的"引擎盖",看看 1.24 亿个参数到底怎么分配的。先算一下每个组件有多少参数。GPT-2 的关键数字:向量维度 d=768,注意力头数 12,FFN 扩展倍数 4,词表 50257,最大位置 1024。Embedding:Token Embedding:每个 token 一个 768 维向量 → 50257 × 768 = 38,597,376Position Embedding:每个位置一个 768 维向量 → 1024 × 768 = 786,432Attention(每层):Q、K、V 三个权重矩阵,每个 768×768 → 3 × 589,824 = 1,769,472输出投影矩阵 O:768×768 = 589,824四个偏置项:768 × 4 = 3,072每层合计:约 236 万FFN(每层):W₁ 扩展矩阵:768 × 3072 = 2,359,296W₂ 压缩矩阵:3072 × 768 = 2,359,296两个偏置项:3072 + 768 = 3,840每层合计:约 472 万(是 Attention 的两倍,因为有 4 倍扩展)LayerNorm(每层):每层两组(Attention 前 + FFN 前),每组有 γ 和 β 各 768 个 → 768 × 2 × 2 = 3,072现在看运行 transformer_anatomy.py[1] 得到的实际分布:组件 参数量 占比──────────────────────────────────────────────────Token Embedding 38,597,376 31.0% ███████████████Position Embedding 786,432 0.6%Attention(12层合计) 28,348,416 22.8% ███████████FFN(12层合计) 56,669,184 45.5% ██████████████████████LayerNorm + 其他 38,400 0.0%三个有意思的发现:FFN 是最大头。 占 45.5%,几乎是 Attention 的两倍。为啥?因为 FFN 有 4 倍扩展(768→3072→768),两个大矩阵。FFN 是"知识库"嘛,存知识当然需要空间。Embedding 在小模型里占比惊人。 GPT-2 的 Embedding 占了 31%。但在更大的模型(比如 LLaMA 7B)里,Embedding 只占 2% 左右——因为模型变大的时候,Transformer 层的参数增长速度远超 Embedding。LayerNorm 小到可以忽略。 只有 38,400 个参数。但没它整个模型就训练不了。最不起眼的组件,反而最不能少。完整拆解和数据流追踪代码见附件 transformer_anatomy.py[1]。 ▍八、为什么要叠这么多层GPT-2 叠了 12 层,LLaMA 7B 叠了 32 层。能不能把一层做得特别大,只用一层搞定?不行。原因有两个。8.1 不同层看不同层次的东西就像人理解一句话,有从浅到深的过程:第三篇的实验展示过:同一个词 "bank",在"银行"和"河岸"两个语境下,向量差异是一层一层加大的:Layer 0: 相似度 1.000 ← 完全一样("这个 bank 啥意思我还不知道")Layer 3: 相似度 0.887 ← 开始有点不同了("后面好像跟了 money...")Layer 6: 相似度 0.778 ← 差距越来越大Layer 9: 相似度 0.691Layer 12: 相似度 0.614 ← 彻底区分了("这个是银行,那个是河岸")浅层做粗活,深层做细活。一层搞不定的事情,叠几层就能搞定。8.2 多层 = 多步推理有些理解需要想好几步。比如这句话:"The trophy doesn't fit in the suitcase because it is too big"——这里的 "it" 指 trophy 还是 suitcase?浅层:先认出 "it" 是代词,要找它指的是谁中间层:注意到 "too big" 说的是尺寸深层:推理——"太大"所以放不下。放不下的应该是 trophy(要是 suitcase 太大,反而装得下啊)。所以 "it" = trophy一步到位做不出这种推理。每多一层,模型就多一次"想一想、改一改"的机会。层数不是越多越好,但深度确实带来推理能力。 ▍九、完整架构图:把所有积木拼起来到这里,所有零件你都认识了。拼在一起:输入文本: "Thank you very" │ ▼ ─── 分词(第二篇)[10449, 345, 845] ← 3 个 token ID │ ├─▶ Token Embedding(查表) ← 3 个 768 维向量 ├─▶ Position Embedding(查表) ← 3 个位置向量 ▼ ─── 加在一起(第三篇)[向量₁, 向量₂, 向量₃] ← 初始表示 │ │ ┌────────────────────────────────────────┐ │ │ Transformer Layer × 12 │ │ │ │ │ │ LayerNorm → Attention(12头)→ 残差 │ ← 开会 │ │ LayerNorm → FFN(768→3072→768)→ 残差 │ ← 独立思考 │ │ │ │ └────────────────────────────────────────┘ │ ↑ 重复 12 次(GPT-2)/ 32 次(LLaMA 7B) │ ▼ ─── 最终 LayerNorm ▼ ─── LM Head(768 → 50257) ▼ ─── Softmax[..., P("much")=0.992, ...] ← 50257 个概率 │ ▼ ─── 选 token(第一篇)" much"就这些了。没有更多隐藏模块。GPT-4、Claude、LLaMA、DeepSeek——底层全是这个结构。区别只在三个数字:同样的架构,放大规模而已。所以用 GPT-2 理解原理,跟用 GPT-4 完全等价。 ▍十、LM Head 与权重共享架构图最后的 "LM Head(768→50257)" 把向量变回 50257 个概率——模型内部一直在操作向量,这一步翻译回"每个词有多大可能性"。很多模型(包括 GPT-2)中,LM Head 和 Token Embedding 共享同一个权重矩阵——同一张 50257×768 的表,进去的时候按行查向量,出来的时候做矩阵乘法算概率。12 层 Transformer 的任务,就是把最后一个位置的向量推向 "much" 对应的方向。推得越准,概率越高——第一篇看到的 99.2% 就是这么来的。 ▍十一、五篇回顾到这里,前五篇构成了一条完整的链路。大模型从输入到输出的每一步,你都看过了:前五篇回答了"大模型是什么"。 后五篇回答"怎么变得更好":训练(第六篇)、推理优化(第七篇)、上下文窗口(第八篇)、Scaling Law(第九篇)、和 Agent 结合(第十篇)。 ▍十二、结语回头看,Transformer 简单到令人吃惊。总共就两种核心运算——Attention(开会讨论)、FFN(独立思考)。加上 LayerNorm 统一格式、残差连接保留原件,然后重复 N 次。同一个结构,拿去翻译、写代码、做数学、聊天——通通能用。你不需要给每种任务设计不同的模型,只需要把这个简单结构做得足够大。"The unreasonable effectiveness of simple architectures."架构够通用,规模就是最好的武器。下一篇,我们讲这些参数怎么从一堆随机数变成能对话的"大脑"——70 亿个数字,是怎么"学"出来的。本文配套代码:transformer_anatomy.py[1](模型拆解、参数统计、数据流追踪、残差连接验证)。需要 Python 3.8+、transformers、torch。 扫码回复“大模型”获取本系列文章完整配套代码「从零开始理解大模型」是「从零开始理解 Agent」的姊妹系列。Agent 系列讲"四肢",本系列讲"大脑"。建议对照阅读 专栏入口。 相关链接[1] transformer_anatomy.py: cid:link_0
-
欢迎阅读「从零开始理解大模型」系列 —— 十篇文章,从"下一个词预测"到完整的大模型心智模型。每篇配可运行代码。第一篇:一切从"猜下一个词"开始第二篇:Token——大模型眼中的"字"长什么样第三篇:向量与 Embedding——把文字变成数学第四篇:Attention——大模型的"阅读理解"机制(本文)第五篇:Transformer 全景——积木怎么搭成大厦第六篇:训练——70 亿个参数是怎么"学"出来的第七篇:推理——你按下回车后的这一秒发生了什么第八篇:上下文窗口——大模型的"工作记忆"第九篇:Scaling Law——为什么"大力出奇迹"有效第十篇:从大模型到 Agent——下一个词预测如何长出手脚* 本文实操配套代码附件,可在本公众号后台回复“大模型”获取。作者:十一上一篇结尾的链路图中间有一个最大的黑盒:[向量₁', 向量₂', 向量₃'] ← Embedding + 位置编码(第三篇) │ ▼ 进入 Transformer │ ← 这里面发生了什么? ▼ P("much") = 99.2%我们知道 Embedding 给每个词发了一张"特征身份证",但也看到了它的局限——"bank" 不管出现在"I deposited money at the bank"还是"The river bank",查出来的初始向量都一样。模型需要一种机制来读上下文,根据周围的词判断 "bank" 是"银行"还是"河岸",修正每个向量的含义。这个机制就是本篇的主角——Attention(注意力机制)。 ▍一、先说结论一句话总结:Attention 让每个词能"看见"上下文中的所有其他词,并决定该重点关注谁。 ▍二、用"图书馆找书"来理解 Attention想象你走进图书馆,要找关于"量子物理"的信息。你不会把每本书从头到尾读一遍——你会先扫视书架上每本书的标签,大脑自动给它们打分:《量子力学入门》95 分、《经典力学》40 分、《烹饪指南》0 分。然后你把绝大部分精力花在读高分那本书的内容上。Attention 做的就是这个过程,对应三个角色:Query(Q):"量子物理"——你带着的搜索需求Key(K):书架上每本书的标签——用来和你的需求做匹配Value(V):每本书的实际内容——匹配成功后你真正要读的东西完整流程:Q 和每个 K 匹配打分 → 分数高的权重大 → 按权重把所有 V 的内容加起来。回到大模型:模型在处理 "Thank you very ___" 时,最后一个位置(要预测的位置)带着自己的 Query 去"扫视"前面所有词的 Key,发现 "Thank" 和 "very" 的分数最高,于是把它们的 Value 信息重点融合进来——这样 "much" 就获得了最高的预测概率。 ▍三、Q、K、V 怎么来的每个 token 经过 Embedding 后是一个向量(比如 768 维)。Attention 不直接用这个原始向量,而是通过三个权重矩阵,变换出三个不同角色的向量:原始向量 (768维) ├── × W_Q ──→ Query (64维) "我在找什么?" ├── × W_K ──→ Key (64维) "我能提供什么索引?" └── × W_V ──→ Value (64维) "我的实际内容是什么?"为什么要三个不同的向量?因为同一个词在不同角色下需要展示不同的面。比如 "Thank":作为 Query 时它在找和自己搭配的词;作为 Key 时它广播自己是一个感谢用语;作为 Value 时它提供"感谢"的具体语义。W_Q、W_K、W_V 就是权重——训练时调整,推理时固定。第三篇提到的"开源权重中 Attention 占约 49%",主要就是这些矩阵。 ▍四、Attention 的三步计算整个过程可以用一个公式概括:Attention(Q, K, V) = softmax(Q · Kᵀ / √d) · V别被公式吓到——它只是下面三步的缩写。Q · Kᵀ 是第一步(打分),softmax 是第二步(归一化),· V 是第三步(加权求和),√d 是缩放因子防止数值太大。以 "Thank you very" 为例,3 个 token 已经通过 Embedding 变成了向量,现在做 Attention。4.1 第一步:打分(公式中的 Q · Kᵀ / √d)每个词的 Query 和所有词的 Key 做点积,得到相关度分数: Key Thank you very Query Thank [ 0.8 0.2 0.3 ] you [ 0.3 0.5 0.4 ] very [ 0.6 0.2 0.7 ] ← "very" 关注 "Thank" 和自己分数怎么算的? 以 "very" 对 "Thank" 的 0.6 为例:把 "very" 的 Query 向量和 "Thank" 的 Key 向量逐元素相乘再求和(点积):Q(very) · K(Thank) = q₁×k₁ + q₂×k₂ + ... + q₆₄×k₆₄ = 0.6点积越大,说明两个向量方向越一致——Q 要找的和 K 能提供的越匹配。这和第三篇的余弦相似度是同一个直觉。实际模型还会除以 √d(如 √64 = 8),防止点积数值过大导致 Softmax 输出太极端。"打分"到底在打什么分? 这个分数同时承载了三层含义:相似度分。 从向量数学看,点积衡量的是方向一致性。Q(very) 和 K(Thank) 方向接近 → 分数高 → 模型认为当前查询需求和这个位置的信息高度匹配。贡献度分。 这个分数决定了对应的 Value 应该贡献多少信息。分高 → 这个位置的内容对当前上下文重要;分低 → 是"噪声",在后续加权求和时会被过滤掉。注意力分配分。 面对一串 token,模型不可能给所有词同等关注。打分就是在回答:"为了理解当前的词,我应该花多少精力去'看'其他词?"——这就是"注意力"这个名字的由来。就像你在图书馆不会平均阅读每本书,而是把精力集中在最相关的那几本上。4.2 第二步:归一化(公式中的 softmax)把每一行的分数转成概率(加起来等于 1): Key(归一化后) Thank you very Query Thank [ 0.46 0.24 0.30 ] you [ 0.27 0.33 0.40 ] very [ 0.36 0.24 0.40 ] ← 40% 注意力给自己,36% 给 "Thank"怎么算的? 以 "very" 那行 [0.6, 0.2, 0.7] 为例,Softmax 先对每个分数取 e 的指数,再除以总和:e^0.6 = 1.82, e^0.2 = 1.22, e^0.7 = 2.01 总和 = 5.05 归一化: [1.82/5.05, 1.22/5.05, 2.01/5.05] = [0.36, 0.24, 0.40]效果:分数高的被放大,低的被压缩,加起来恰好等于 1——变成了概率分布。这和第一篇预测下一个词时的 Softmax 是同一个操作。4.3 第三步:加权求和(公式中的 · V)用注意力分布作为权重,把所有词的 Value 向量加权求和:"very" 的新向量 = 0.36 × Value(Thank) ← 贡献最大 + 0.24 × Value(you) + 0.40 × Value(very)结果:"very" 的向量里融合了 "Thank" 的信息。当模型用这个新向量预测下一个词时,它"知道"前面是 "Thank you very"——所以 "much" 的概率被大幅提高。Attention 的全部运算就是这三步:打分 → 归一化 → 加权求和。 没有循环,没有条件判断,都是矩阵乘法。 ▍五、实际看 Attention 分数用代码可以提取 GPT-2 真实的 Attention 矩阵:outputs = model(input_ids, output_attentions=True) attention = outputs.attentions[0][0, 0] # Layer 0, Head 0 # attention.shape: [3, 3] ← 3 个 token 之间的注意力分数对 "Thank you very" 的实际结果(文末 attention.py 可以复现):Layer 0, Head 0: Thank you very Thank │ 1.000 · · ← 只能看自己 you │ 0.960 0.040 · ← 96% 注意力给了 "Thank" very │ 0.670 0.180 0.149 ← 67% 注意力给了 "Thank"几个关键观察:"Thank" 那行只有一个 1.000。 它是第一个词,只能看自己(因果掩码),所以 100% 注意力在自己身上。"you" 和 "very" 都重点关注 "Thank"。 这很合理——"Thank" 是这句话的核心语义(感谢),后面的词都需要从它那里获取信息来做出正确预测。右上角全是 ·(零)。 每个词只能看自己和前面的词,不能看后面——这就是因果掩码(Causal Mask)。这就是因果掩码(Causal Mask)——推理时后面的词还没生成,模型不能偷看未来。矩阵右上角全是 0:✓ ✗ ✗ "Thank" 只能看自己 ✓ ✓ ✗ "you" 能看前 1 个词 ✓ ✓ ✓ "very" 能看所有词 ▍六、多头注意力:同时从多个角度看GPT-2 每一层有 12 个注意力头,每个头独立做一套 Q/K/V 计算。为什么要多个头?因为一句话需要从多个角度理解:# 提取所有 12 个头对 "very" 的注意力分布 for head in range(12): att = outputs.attentions[0][0, head, -1, :] # "very" 的注意力 max_token = tokens[att.argmax()] print(f"Head {head}: 最关注 '{max_token}'")不同的头会关注不同的东西——有的头关注语法搭配("very" → "Thank"),有的关注相邻位置("very" → "you"),有的关注自身。12 个头从 12 个角度读同一句话,拼在一起就是全面的理解。没有人告诉 Head 0 去关注语法、Head 3 去关注位置。这些分工是训练过程中自动形成的——每个头学到了一种对预测下一个词有用的关注模式。每个头的 Q/K/V 维度是 64(= 768 / 12),12 个头的结果拼接起来还是 768 维:Multi-Head Attention = Concat(Head₁, Head₂, ..., Head₁₂) × W_O 每个 Headᵢ = Attention(Q_i, K_i, V_i) // 独立计算,64 维 拼接后: 12 × 64 = 768 维 W_O: 输出投影矩阵,768 × 768完整的多头注意力分析代码见附件 multi_head.py。* 本系列文章完整实操配套代码,可在公众号后台回复“大模型”获取。 ▍七、Attention 在完整链路中的位置把第四篇学到的内容嵌入之前的链路:"Thank you very" │ ▼ 分词(第二篇) [10449, 345, 845] │ ▼ Embedding + 位置编码(第三篇) [向量₁, 向量₂, 向量₃] ← 初始向量 │ ▼ Attention(本篇)—— 打开的黑盒 │ 每个向量生成 Q、K、V │ Q · Kᵀ / √d → 打分 │ softmax → 注意力分布 │ 加权求和 V → 融合上下文 │ 12 个头并行,结果拼接 ▼ [新向量₁', 新向量₂', 新向量₃'] ← 融合了上下文 │ ▼ 还有 FFN、残差连接...(第五篇) ▼ 重复 12 层 ▼ → softmax → P("much") = 99.2%但 Attention 只是一层中的一半——另一半是 FFN(前馈网络)和"胶水"组件(残差连接、LayerNorm)。它们一起构成一个完整的 Transformer 层,堆叠几十层才是最终模型。这是下一篇的主题。 ▍八、n² 的代价Attention 的注意力分数矩阵是 n × n(n 为 token 数)。每个词要和所有词算相关度:输入 100 tokens → 100 × 100 = 10,000 次计算 输入 1,000 tokens → 1,000² = 1,000,000 次 输入 10,000 tokens → 10,000² = 100,000,000 次长度增 10 倍,计算量增 100 倍。这就是为什么长文本慢、显存占用大、各种"高效 Attention"变体都在想办法降低 n²。第八篇(上下文窗口)会详细讲。 ▍九、结语Attention 不神秘。它做的事情用一句话就能说清:让每个词看看上下文中的所有词,算出该关注谁,然后把被关注词的信息融合到自己身上。三步运算——打分、归一化、加权求和。多个头并行,从不同角度做同样的事。因果掩码确保只能看过去,不能偷看未来。"Attention is all you need." — Vaswani et al., 20172017 年那篇论文的标题恰如其分。Attention 让每个词能一次性看到整个上下文,这个简单的改变带来了革命性的效果。下一篇,我们把 Attention、FFN、残差连接、LayerNorm 组装起来,看一个完整的 Transformer 层长什么样。本文配套代码:attention.py(Attention 矩阵可视化)、multi_head.py(多头注意力分析)。需要 Python 3.8+、transformers、torch。 扫码回复“大模型”获取本系列文章完整配套代码「从零开始理解大模型」是「从零开始理解 Agent」的姊妹系列。Agent 系列讲"四肢",本系列讲"大脑"。建议对照阅读 专栏入口。
推荐直播
-
华为云码道全新升级,多会话并行与多智能体协作2026/05/08 周五 19:00-21:00
王一男-华为云码道产品专家;张嘉冉-华为云码道工程师;胡琦-华为云HCDE;程诗杰-华为云HCDG
华为云码道4月份版本全新升级,此次直播深度解读4月份产品特性,通过“特性解读+实操演示+实战案例+设计创新”的组合,全方位展现码道在多会话并行与多智能体协作方面的能力,赋能开发者提升效率
回顾中
热门标签