ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

vllm-ascend 持久化增量 csrc 构建缓存(Persistent Incremental Csrc Build Cache)设计全解析

vllm-ascend 持久化增量 csrc 构建缓存(Persistent Incremental Csrc Build Cache)设计全解析 人工智能大模型模型推理服务AscendCANN【免费下载链接】vllm-ascendCommunity maintained hardware plugin for vLLM on Huawei Ascend项目地址https://gitcode.com/gh_mirrors/vl/vllm-ascend点击查看免费下载导读本文基于 vllm-ascend 仓库的设计文档 persistent_csrc_build_cache.md系统讲解 vLLM Ascend 为原生第三方库与大量 AscendC 自定义算子构建引入的持久化增量 csrc 构建缓存L1 缓存。文章覆盖缓存的两级架构、动作身份action identity的三元哈希模型、CMake 集成契约、快照密钥与传输信任模型、并发锁机制、失败行为矩阵以及四类集成模式并结合仓库内真实实现build_cache.py、build_cache.cmake、prepare_csrc_l1_restore.py 与两个 GitHub Action逐层印证。读完本文你将理解精确产物缓存之外的增量复用层如何在 CI、本地反复构建与历史源码构建之间安全复用编译动作并掌握排障时应该检查的缓存身份字段与诊断路径。为什么需要两级缓存问题与设计动机vLLM Ascend 的构建过程包含两类重量级原生工作原生第三方库如 protobuf 等由 csrc/cmake/third_party/ascend_protobuf.cmake 定义语义输入大量 AscendC 自定义算子如 attention、moe、gmm 等目录下的自定义算子语义输入声明于 csrc/cmake/func.cmake。仓库原有的 L0 缓存是一种精确最终产物缓存exact final-artifact cache只要完整的产物密钥匹配就能跳过整个原生构建。它的代价是任何源码变化都会使完整产物整体失效即使只改动了一个算子的一个头文件也必须重新编译整批原生库。持久化增量 csrc 缓存L1正是为此新增的第二级缓存它复用**单个编译动作compiler action**的已验证产物且复用范围跨越 CI 任务jobs、不同工作区workspaces以及反复进行的本地源码构建。两级缓存的分工如下L0 exact final artifact | | miss v L1 persistent action entries | v ordinary source build关键在于源码构建source build始终是权威。L1 不会绕过源码构建的语义它只是用先前已验证的等价动作产物替换一次等价动作的执行而且这种替换必须经过逐项校验。从设计文档的 Goals 与 Non-goals 可以提炼出本缓存的边界目标跨 CI 任务复用原生构建工作在没有远程传输的情况下跨多次本地源码构建复用只让语义输入发生变化的动作失效跨等价 checkout 与构建根复用条目通过仓库既有缓存传输机制持久化本地条目在并发构建下安全发布产物当可选缓存层不可用时优雅降级为普通构建。非目标不替代编译器自身的依赖跟踪不替代 L0 最终产物缓存不在物理节点之间共享文件锁不要求历史源码快照自带缓存引擎不对旧缓存 schema 做原地迁移。架构与正确性边界整个系统的职责被有意分层workflow | -- restore L1 snapshot | -- CMake adapter | | | -- action identity | -- entry lookup/validation | -- restore or compile | -- local entry save | -- custom-operator publication | -- publish changed L1 snapshot (writers only)对应到仓库实现csrc/scripts/build_cache.py约 1757 行独占本地动作身份、条目、加锁、恢复与发布能力是缓存引擎本体csrc/cmake/build_cache.cmake 由 CMake 声明语义输入并调用引擎其中vllm_ascend_build_cache_command()是一个正确性敏感边界不只是命令包装器组合动作composite actions独占持久化快照密钥与 OBS 传输工作流只决定从哪里恢复快照以及哪些受信任的构建角色可以发布。L0 与 L1 的正确性边界两级缓存各自拥有独立的正确性边界L0 是外层精确最终产物快照只有当完整产物密钥匹配时命中才能跳过原生构建L1 是外层本地动作缓存的持久化快照恢复 L1 快照只让候选条目可用引擎内部仍须校验每个条目的 manifest、动作密钥、schema、产物模型artifact model与产物内容通过后才接受该条目。因此L1 命中永远不会覆盖内层正确性L1 未命中也永远不会改变一次正常源码构建的正确性。设计文档特别强调了一个 L0 的隐患现有镜像构建的 L0 密钥使用架构 基础镜像标签 被跟踪的 csrc 哈希。由于 L0 命中会跳过编译、也就跳过了 L1 条目校验该密钥隐含假设编译器镜像仓库固定 镜像标签不可变。如果更换镜像仓库或对同一标签重新发布不同内容的镜像就必须更换新的 L0 密钥命名空间或在密钥中加入完整镜像身份——L1 身份检查无法让已被接受的 L0 产物变得安全。当前设计文档所对应的变更并未改变镜像构建 L0 的行为也未给 Docker 构建附加 L1。构建流程冷构建与热构建冷构建Cold buildL0 miss - L1 miss - normal source build starts - action MISS - compiler runs - verified local entry save - .updated marker - writer publishes L1 - optional L0 publication热构建Warm buildL0 miss - compatible L1 snapshot restored - .updated marker reset - normal source build starts - action identity calculated - entry validated - action HIT - artifacts restored - compiler action skipped一个值得注意的细节全命中all-HIT构建不会重建.updated标记因此不会发布新的唯一远程快照。也就是说只有本地缓存真正新增或替换了条目引擎在新保存或替换条目后才会写.updated才具备远程重新发布的条件避免每次 CI 都产生一个无意义的唯一快照。该行为与 csrc-l1-save 动作 中presenttrue的判定逻辑同时要求 primary key 非空、本地目录存在且存在.updated文件一一对应。缓存身份动作密钥的三元哈希每个动作的密钥是三个独立身份的规范哈希canonical hashprepared_input_hash what is compiled 编译什么 recipe_hash how it is compiled 如何编译 compiler_environment_hash which toolchain 用什么工具链编译在 build_cache.py 的文件头注释中这三者被描述为缓存等价关系的核心且缓存引擎不拥有任何静态的算子或第三方单元清单——单元清单完全由 CMake 层动态声明。对于自定义算子另有operator_text_hash提供算子命名空间namespaces 自定义算子条目但它不替代上述三个动作密钥组件中的任何一个。条目 manifestentry manifest保存这些哈希以及密钥所用的精确产物模型artifact model。一次 HIT 必须同时满足期望的 schema、域domain、动作密钥、产物模型与已验证的产物内容。仓库中ARTIFACT_MODEL_BY_DOMAIN {third_party: 1, custom_operator: 2}build_cache.py表明产物模型按第三方库 / 自定义算子两个域分别编号。预处理输入契约Prepared-input contract预处理输入prepared inputs覆盖所有编译器可见的语义内容包括生成的算子源码generated operator sources依赖的生成源码dependent generated sources共享内核源码shared kernel sources编译器可见的 recipe 文件共享兼容头文件例如cann_compat.h。根路径归一化root normalization物理的 checkout 根与构建根不是语义身份。因此对于显式声明的根UTF-8 文本可以做归一化处理。但归一化有严格前提只有当通过该根引用的每个语义对象都被动作身份独立覆盖时该根才能被归一化。设计文档给出的示例是生成的 adapter 中可能包含-include /temporary/root/csrc/common/include/cann_compat.h这里临时根/temporary/root被归一化即被替换为占位形式而cann_compat.h的内容作为预处理输入被哈希。于是移动工作区仍是 HIT修改该头文件则变成 MISS。归一化契约被刻意收窄仅 UTF-8 文本、仅在路径组件边界处替换显式归一化根源码中无关的反斜杠、转义序列与正则表达式仍保持字节敏感二进制输入保持原始字节敏感显式根之外的路径仍敏感符号链接身份与其解析后的语义内容同时参与哈希一个不可读的显式语义输入绝不会被静默地从身份中省略。Recipe 与编译器环境身份Recipe 身份覆盖编译命令、recipe 文件以及遵循同一根归一化契约的显式 recipe 值。--set-env编译器覆盖项也参与身份计算使用其精确值——因为一个覆盖项可能指向一个未被预处理输入身份覆盖的输入。编译器环境身份覆盖宿主平台、选定的编译器 profile、工具版本输出、CANN 元数据与显式环境值。当所报告的工具身份相等时编译器安装的绝对路径不构成语义差异。CMake 集成契约正确性敏感边界vllm_ascend_build_cache_command() 是csrc构建中所有可缓存动作的统一入口。任何调用方只要改变了一个编译器可见输入就必须在同一份变更中更新对应的身份组身份参数语义PREPARED_INPUT描述源文件、生成文件、依赖文件与共享内容what is compiledRECIPE_FILE/RECIPE_VALUE描述这些内容如何被构建how it is compiledSET_ENV改变编译器进程环境只要其值可能影响输出就必须保留在 recipe 身份中ENVIRONMENT_FILE/ENVIRONMENT_VALUE/ENVIRONMENT_TOOL描述编译器/工具链环境which toolchainNORMALIZE_PATH只移除一个物理位置且该位置引用的语义内容已被上述身份组覆盖函数签名中的其余参数DOMAIN、UNIT、SOC、OPERATOR、OPERATOR_SOURCE、REPO_ROOT、OUTPUT_DIR、PUBLISH_DIR、PUBLISH_STATE_DIR、ENVIRONMENT_PROFILE、ARTIFACT_INCLUDE、EXCLUDE、COMMAND等定义产物所有权OUTPUT_DIR、PUBLISH_DIR、PUBLISH_STATE_DIR与ARTIFACT_INCLUDE决定产物归属自定义动作必须保持私有输出 串行化共享发布。调用方默认会被自动附加--normalize-path指向CMAKE_SOURCE_DIR与CMAKE_BINARY_DIRbuild_cache.cmake这正是归一化契约在适配层落地的方式。设计文档给出两条明确警示删除或遗漏一个身份参数可能造成假命中false HIT加入一个非语义的物理路径可能造成可避免的跨工作区未命中cross-workspace miss。因此对自定义算子生成输入的改动、或对 protobufExternalProject_Add()命令的改动都必须做一次缓存身份评审。Schema 与快照兼容性条目 schema条目 manifest 使用SCHEMA_VERSION 4build_cache.py。Schema 4 引入了安全的文本预处理输入归一化并让归一化路径具备完整语义覆盖。旧条目自然未命中因为持久化密钥包含 schema且条目校验会拒绝不同 schema——不存在原地迁移schema 4 的首次构建是冷构建之后才是热构建。设计文档还明确了命名空间纪律Schema 4 是该缓存第一个生产命名空间。此前 schema-4 候选版本写入的预发布本地或验证快照与生产不兼容必须与生产命名空间隔离。任何未来可能把旧语义输入映射到不同含义的变更都应触发 schema 或身份修订而不是复用旧条目。PUBLISH_STATE_SCHEMA仓库中取值为 1build_cache.py是独立变量因为构建树产物所有权是与持久化条目身份不同的格式。快照密钥兼容模型快照密钥命令snapshot-key由 prepare_csrc_l1_restore.py 调用只有一种兼容模型schema architecture canonical SOC explicit compiler-image identity for a nested container build 或 CANN metadata runtime OS/libc identity for a direct buildrestore 动作在此基础上追加被跟踪的 csrc 哈希与唯一发布后缀唯一后缀由GITHUB_RUN_ID、GITHUB_RUN_ATTEMPT、时间戳、PID 与随机 token 拼成见 prepare_csrc_l1_restore.py。因此生产者与消费者的密钥都来自同一实现。两个细节值得注意显式编译器镜像优先于外层 runner 环境——Docker 构建以实际编译 csrc 的环境为密钥直接构建包含运行时 OS/libc 身份——避免宿主构建的产物跨越不兼容的系统头文件或 ABI 边界。架构与 SOC 别名在 build_cache.py 中被归一化如x86_64/amd64→x64aarch64→arm64SOC 如a2/910b→ascend910b1a3→ascend910_9391其中 560T runner 与 A3 共享 csrc target工具链身份仍会区分。Prepare、restore 与 save 动作prepare_csrc_l1_restore.py 是共享密钥准备助手校验被测源码根包含缓存引擎csrc/scripts/build_cache.py存在当调用方未提供 csrc 哈希时用git ls-files -s对csrc、setup.py、CMakeLists.txt、cmake计算 SHA-256无跟踪清单时返回adhoc计算快照密钥并导出VLLM_ASCEND_BUILD_CACHE_DIR与事件日志路径。不可支持或无法识别的源码快照返回supportedfalse调用方继续普通构建。.github/actions/csrc-l1-restore/action.yaml 调用该助手用runs-on/cache/restorev5按密钥primary key与两个兼容前缀same_csrc_prefix、compat_prefix恢复外层快照并在构建前删除.updated。.github/actions/csrc-l1-save/action.yaml 仅在以下条件同时成立时发布调用方提供了 primary key、本地缓存包含.updated、且存在受信任的写凭证HW_OBS_AK/HW_OBS_SK。失败语义上restore/save 的传输失败属于可用性失败保持 fail-opencontinue-on-error: true缺失或不可解析的 manifest、或 manifest 对象未通过 schema/产物校验一律视为 MISS 并重新构建可能损坏共享产物发布或同步的冲突则失败构建。设计文档同时披露了一个已知缺陷顶层为非对象的 JSON manifest 目前在校验时抛异常并不在 MISS 回退覆盖范围内。工作流代码与被测源码分离持久化动作引用使用uses: $/.github/actions/csrc-l1-restore与uses: $/.github/actions/csrc-l1-save语法其中$/.github让动作实现从工作流修订版本解析。因此调用方的仓库与source_ref可以是 fork 或历史快照而不会选中一个不兼容的动作实现。调用方输入仍然描述被测 checkoutsource-root、缓存目录、架构、SOC、工具链镜像与可选 csrc 哈希。条目与产物生命周期引擎对每个动作执行如下九步对预处理输入、recipe 与编译器环境做哈希推导内容寻址条目路径content-addressed entry path获取条目锁与动作锁校验并恢复匹配条目否则运行原始构建命令发现并验证产生的产物原子保存本地条目将本地 L1 快照标记为已更新将自定义算子产物发布进共享构建输出。条目 manifest 就是正确性记录查找与失效都不需要额外的可变索引。并发模型三级锁三个锁作用域各自保护不同的不变量锁保护的不变量条目锁entry lock一个内容寻址条目只允许一个创建者动作锁action lock保护单个动作的私有暂存目录发布锁publish lock串行化共享自定义算子输出发布自定义算子编译进私有暂存目录发布时跟踪产物所有权并使用原子替换防止部分输出变得可见。同一相对产物出现冲突的所有者时是硬错误而不是不安全地覆盖。实现层面锁基于fcntl.flock非阻塞尝试加锁 轮询等待轮询间隔LOCK_POLL_SECONDS 0.05秒并通过环境变量可调超时条目锁默认 60 秒、动作锁与发布锁默认 120 秒build_cache.py。锁类型由路径推断.publish.lock→ publish.action_locks目录下 → action其余 → generic。多节点任务使用节点作用域缓存目录/root/.cache/vllm-ascend/csrc-build-cache/soc/node-worker设计明确不依赖跨节点flock行为。持久化传输与信任模型restore 与 save 组合动作独占固定的华为 OBS 传输配置桶ascend-ci-cache-hk端点obs.ap-southeast-1.myhuaweicloud.com。缓存引擎本身没有任何存储 API 或凭证知识。信任边界划分清晰读访问沿用 runner 既有的 OBS 授权共享写入要求同时具备HW_OBS_AK与HW_OBS_SK持有这两个密钥是唯一的写授权边界save 动作从受信任调用方显式接收凭证任一缺失即跳过发布。当前集成的角色划分只有中央 csrc 生产者发布 L1镜像与 release-wheel 的 Docker 构建保留既有行为不 restore、不 export、不 save 持久化 L1源码消费任务是只读 L1 消费者可在既有源码安装前恢复兼容快照但不发布精确产物消费者使用中央 L0 输出L0 未命中则进入普通源码构建不把持久化 L1 传输变成前置条件本地编译保持正确但不会创建共享快照。发布者只在成功构建创建或替换了本地条目之后才发布。OBS 的 restore/save 失败一律被视为性能退化。失败行为矩阵条件行为历史源码没有缓存引擎报告 unsupported 并继续普通构建快照环境无法被指纹化跳过 L1 restore 并继续普通构建快照 restore 失败以空本地 L1 继续条目缺失、不可解析或对象 manifest 未通过校验编译并替换它manifest 是合法 JSON 但顶层非对象目前在校验时抛异常这是缓存引擎的待修复缺陷条目锁不可用绕过条目并编译本地条目保存失败警告并保留成功的构建输出快照保存失败保留成功的构建或已验证的 L0 产物编译器命令失败构建失败产物所有权冲突失败而不是覆盖另一动作的输出动作或发布同步失败在继续可能损坏共享输出时失败可观测性方面操作型 JSONL 事件仅限于缓存结果、警告与锁竞争观测是尽力而为绝不串行化编译事件通过VLLM_ASCEND_BUILD_CACHE_EVENT_LOG环境变量指向的日志文件追加写入见 build_cache.py。集成模式直接源码消费者源码消费任务在既有源码安装前恢复 L1 且不发布。精确产物任务使用中央生产者的 L0 输出L0 未命中时走其既有源码构建不额外做第二次直接 L1 回退除非调用方显式启用可选的共享 L1 回退selected-test 任务在 L0 未命中后使用该可选回退其他 L0 消费者包括定时上游 E2E保留各自调用方特定的源码构建策略。本地源码构建普通本地源码构建使用仓库中被 gitignore 的csrc/build_cache目录里的同一动作缓存。这是纯本地加速不涉及 OBS 凭证也没有远程快照传输。可通过设置环境变量VLLM_ASCEND_BUILD_CACHE_DIR为绝对路径来覆盖本地默认位置CI 总是提供显式目录不受仓库本地位置影响。删除本地目录会导致一次冷构建但不会改变被编译的源码或 CI 的持久化快照。对应到 build_cache.cmake 的解析优先级CMake 变量VLLM_ASCEND_BUILD_CACHE_DIR 环境变量 默认CMAKE_SOURCE_DIR/build_cache即csrc/build_cache。中央生产者可复用生产者.github/workflows/_build_csrc_cache.yaml 中的Build csrc Cache工作流的完整链路为restore L1 → 普通源码构建 → 校验最终原生产物检查vllm_ascend顶层存在*.so→ 发布变更的 L1 状态csrc-l1-save→ 发布精确 L0 产物runs-on/cache/savev5密钥形如vllm-ascend-build-v2-arch-image_tag-csrc_hash。该工作流按csrc_cache_targets.json解析出的 target 矩阵运行架构、SOC、镜像、runner 各异并支持在给定base_sha时将源码 rebase 到固定基线快照后再构建确保缓存密钥与测试消费的快照一致。历史源码Main2Main 与 bisect 式构建把当前工作流助手与所选源码树分离。不含build_cache.py的历史树会报告supportedfalse并正常构建——这正是不要求历史源码快照包含缓存引擎这一非目标在实现上的落地。Docker 构建镜像与 release-wheel 工作流在本变更中既不是 L1 消费者也不是写入者。其既有 Docker 构建、源码编译与镜像 L0 行为保持不变后续集成必须在不在发布镜像中嵌入持久化 L1的前提下验证 Docker 边界。验证总结设计文档给出的验证证据矩阵如下能力证据动作身份、条目与失败行为缓存引擎单元测试并发所有权与锁行为并发单元测试直接源码复用A2、A3 与 310P 冷/热运行选择性失效算子局部变更 无关动作保持 HIT与根无关的语义身份schema-4 CASE-C 回归持久化生产者冷/热生产者运行同时文档诚实指出部分精确生产调用方仍需要发布凭证、调用方注册或多节点分配结构性/组件级证据并不能替代这些调用方特定的运行时门槛。运维排障指南意外的全 MISS逐一对比 schema、快照兼容性、prepared_input_hash、recipe_hash、compiler_environment_hash与条目 manifest大范围选择性失效broad selective invalidation检查预处理输入集合与算子命名空间operator_text_hash相关——很可能有遗漏的语义输入或过宽的归一化历史源码场景检查 restore 动作的supported输出false表示正常降级为普通构建。实现地图职责源码位置缓存身份、条目、加锁与发布csrc/scripts/build_cache.pyCMake 到引擎的适配器csrc/cmake/build_cache.cmake算子语义输入csrc/cmake/func.cmake第三方库语义输入csrc/cmake/third_party/ascend_protobuf.cmake持久化 restore 与密钥编排.github/actions/csrc-l1-restore/action.yaml持久化变更快照发布.github/actions/csrc-l1-save/action.yaml密钥准备助手.github/workflows/scripts/prepare_csrc_l1_restore.py中央生产者.github/workflows/_build_csrc_cache.yaml小结持久化增量 csrc 构建缓存是 vllm-ascend 构建体系中的一个分层加速器它以内容寻址的动作条目 三元身份哈希 严格校验为内核以外层 L1 快照 OBS 传输 受信任写入者为持久化边界始终把源码构建的正确性放在第一位。无论你是想加速本地反复编译、理解 CI 缓存密钥的构成还是排查一次意外的缓存未命中都可以从本文的三元哈希模型、schema 兼容模型与失败行为矩阵入手定位问题。赞分享人工智能大模型模型推理服务AscendCANN【免费下载链接】vllm-ascendCommunity maintained hardware plugin for vLLM on Huawei Ascend项目地址https://gitcode.com/gh_mirrors/vl/vllm-ascend点击查看免费下载相关推荐Hasura 增量缓存库 incremental 解析用 ArrowCache 加速 Schema Cache 重建Hasura 增量缓存库 incremental 解析用 ArrowCache 加速 Schema Cache 重建 incremental 是 Hasura后端API网关数据库GraphQL如何在SwiftUI中集成RainbowNavigation打造炫酷导航栏动画的终极指南如何在SwiftUI中集成RainbowNavigation打造炫酷导航栏动画的终极指南 RainbowNavigation是一个强大的iOS导航栏动画库专Theatre构建缓存策略持久化缓存与增量构建Theatre构建缓存策略持久化缓存与增量构建 你是否还在为前端项目构建耗时过长而烦恼每次修改代码后等待数分钟的编译过程不仅降低开发效率更会打断创作思路。前端上一篇番茄小说下载器你的个人数字图书馆构建利器下一篇ComfyUI-VideoHelperSuite完整使用指南从入门到精通创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表