跳转至

Dooly: Configuration-Agnostic, Redundancy-Aware Profiling for LLM Inference Simulation

会议: NeurIPS 2026
arXiv: 2605.07985
代码: https://dooly-project.github.io
领域: LLM效率
关键词: 大模型推理模拟, 算子剖析, 动态污点传播, 跨配置去重, 层次化上下文解析

一句话总结

针对现有大模型推理模拟器硬编码算子且全量重复剖析的瓶颈,Dooly 利用单次 dummy 提示推理结合污点传播标记张量来源,并复用推理引擎上下文隔离有状态算子,实现无配置绑定与跨架构算子去重的极速剖析,在保证模拟误差 <8% 的同时削减 56.4% 的剖析 GPU 时。

研究背景与动机

在大语言模型(LLM)实际部署与服务化过程中,工程师必须在异构硬件(如 A100、H100)、推理服务引擎(如 vLLM、SGLang)、注意力后端算子(如 FlashAttention、FlashInfer、TritonAttention)以及多样化的模型架构间做组合选型。不同工作负载(Prefill 主导或 Decode 主导)和上下文序列长度下,最优配置组合往往出现逆转(Inversion),甚至次优配置会带来成倍的延迟劣势。由于在线全量暴力测试极度昂贵,基于执行剖析的模拟器(如 Vidur、Revati、LLMServingSim)成为了部署前性能评估的标准基础设施。

然而现有的剖析模拟器存在两个关键结构性缺陷。其一,静态配置依赖性严重:现有工具将剖析的算子集合及调用参数深度硬编码在针对特定引擎或模型家族的手写模板中,一旦底层软件栈版本更新、引入算子融合或出现新型网络拓扑,模拟器就会失效,需要消耗大量工程人力重新适配。其二,剖析开销极其高昂:由于现有模拟器将 GPU 视为黑盒,无法识别不同配置背后相同的底层计算,每次引入新模型或注意力后端都必须从头穷举网格化参数(批大小、提示长度、上下文长度),导致 GPU 消耗时间随探索空间线性膨胀。

这两大痛点的本质在于缺乏对 LLM 推理计算图输入维度的语义结构认知。事实上,每个算子的输入张量维度要么由模型架构配置(如隐层维度、注意力头数)决定,要么由运行时请求特征(如批大小、token 数量)决定,且大量模型配置参数在行业模型家族间高度重复。核心 idea:通过单次 dummy prompt 推理并利用动态污点传播精确区分张量维度的来源,以模型固有维度与后端内核哈希构建算子签名跳过重复剖析,同时复用引擎自身上下文初始化代码无侵入隔离有状态算子,实现与具体软件栈解耦的高效冗余感知剖析。

方法详解

整体框架

Dooly 的架构由剖析引擎 DoolyProf 与模拟驱动模块 DoolySim 两大部分组成。输入为目标模型名称和待探索的系统配置元组,整体流程划分为:通过单次推理生成带语义标签跟踪的执行图、提取最小可运行算子集合、跨配置签名去重并有针对性地参数扫描、最后训练回归模型供调度模拟器回放推理过程。

%%{init: {'flowchart': {'rankSpacing': 24, 'nodeSpacing': 28, 'padding': 6, 'wrappingWidth': 400}}}%%
flowchart TD
    A["输入:目标模型与配置元组"] --> B["动态污点传播<br/>单次 Dummy 推理与来源标签追踪"]
    B --> C["层次化上下文解析<br/>自底向上可运行性测试与模块回退"]
    C --> D["算子签名去重与参数扫描<br/>仅对未命中签名的算子执行维度网格剖析"]
    D --> E["持久化延迟数据库 (SQLite)"]
    E --> F["DoolySim 模拟执行<br/>复用引擎调度器 + 回归模型预测"]

关键设计

1. 动态污点传播:区分模型固有结构与请求驱动维度 在追踪 PyTorch 执行轨迹时,张量形状本身是纯数值,无法分辨某个维度是来自请求批次还是模型超参,直接盲目全维度网格扫描会导致搜索空间爆炸。Dooly 在服务引擎的数据结构入口(如 vLLM 的 ModelConfig 与 SchedulerOutput)注入初始污点标签:模型参数标记为 model_config,请求特征分别标记为 num_toks 与 num_reqs。在单次前向执行期间,污点标签随着标量算术与张量变换规则传播。针对张量操作,Dooly 区分两类机制:对改变形状的维度映射操作(Dimension-Mapping,如 empty、reshape),若涉及合并与拆分则记录组合映射表 mix(H) 并利用冲突/扩展规则维护贡献来源;对维度保持操作(Dimension-Preserving,如大多数激活与线性计算),直接挂载在 PyTorch Dispatcher 拦截层,借助输出输入维度的模式匹配继承污点。这使得后续生成算子签名时,能够严格剔除请求维度,仅保留模型固有维度。

2. 层次化上下文解析:自底向上最小粒度算子隔离 算子级剖析要求每个被测算子能够脱离整体模型独立执行,但注意力机制等有状态算子极度依赖 KV 缓存地址、分页元数据及请求槽位映射,无法仅靠输入张量独立重放。Dooly 构建整个模块调用的树状层次结构,先将结构相同的 Transformer 层子树合并,再自叶子节点向上执行试运行测试。若某个叶子算子缺少环境上下文导致导入或执行失败,Dooly 自动回退至其最近的父级 nn.Module,并直接复用推理引擎本身的初始化接口(如 vLLM 的 set_forward_context())生成并注入对应的执行上下文。若父级模块成功跑通,则在可运行集合中记录该父模块并剔除其所有子节点以防重复计时。这种混合粒度机制确保了算子在可能的最大细粒度被独立隔离,同时具备对复杂有状态内核的兜底覆盖。

3. 算子签名去重与参数扫描:跨配置与跨模型冗余消除 模型间虽然分词器或外部包装不同,但底层计算几何经常完全一致(例如 Qwen-3-8B 与 Llama-3-8B 具有相同的查询头与 KV 头参数)。Dooly 为每个候选算子计算规范签名:由算子类型及 model_config 污点维度值、底层实际派发的 GPU 内核符号(捕获后端编译期特定优化)、以及模块实例的原始 Python 属性摘要(如滑动窗口大小等隐藏分支属性)共同构成,通过 SHA-256 计算哈希键。如果该签名已存在于全局 SQLite 延迟数据库中,则直接跳过剖析;仅针对未命中的签名,固定 model_config 维度,仅对 num_toks 与 num_reqs 维度按指定范围生成张量展开网格基准测试。通信算子(如 TP 通信)则按拓扑与并行度独立建表,实现全架构解耦复用。

损失函数 / 训练策略

Dooly 属于离线性能建模框架,不改动模型权重,其下游延迟预测模块 DoolySim 为每个唯一下标签名拟合回归模型。针对非 Attention 算子,以 token 数量为自变量训练回归函数;针对 Attention 类算子,自变量包含 Prefill token 数、Batch size、Prefill chunk 尺寸以及当前已缓存的上下文长度。端到端模拟回放时,直接挂接 vLLM 自身经过验证的调度器以 100% 保真度生成各 step 的请求调度决策,并在调用图遍历中累加各签名的预测延迟。

实验关键数据

主实验

论文在 NVIDIA A100 与 H100 平台上,针对 12 个 7B–8B 常见主流模型(覆盖 MHA、GQA、滑动窗口注意力架构),在 FlashInfer、FlashAttention、TritonAttention 三大后端共计 36 种配置下进行了全量对比剖析,并评估了端到端模拟精度。

评估项目 核心指标 Dooly 表现 基线方法 (Vidur/Naive) 相对优势/误差
A100 端到端模拟误差 (ShareGPT4) TTFT MAPE < 5.0% 实测基线 (Ground Truth) 预测高度贴合真机
A100 端到端模拟误差 (ShareGPT4) TPOT MAPE < 8.0% 实测基线 (Ground Truth) 处于测量抖动合理范围内
调度逻辑一致性 调度决策误差 < 0.5% vLLM 原生调度器 几近完全重现实际批处理
跨配置剖析开销 (12 模型,36 配置) 总 GPU 耗时 (h) 11.58 h 26.54 h (Naive) 降低 56.4% 剖析时间
算子签名命中率 签名去重率 100 唯一 / 612 次调用 612 次全量测试 去除 83.7% 的冗余剖析项

在算子剖析策略的横向对比中,不同粗细粒度的复用策略展现出明显性能与准确度差距:

剖析方法 剖析耗时 (GPU-hours) 节省比例 (%) 跨异构注意力预测准确度
Naive (全量逐个配置剖析) 26.54 0.0% 基准参考
HF-Diff (全量 HF 配置文件比对) 24.44 7.9% 无法跨模型复用算子
HF-Model-Diff (模型超参比对) 15.97 39.8% 无法感知滑动窗口等分支,误差达 37.3%
Dooly (本文方法) 11.58 56.4% 保持算子级感知,误差仅 4.1%

消融实验

针对动态污点传播规则的完备性,论文对比了维度映射(DM)和维度保持(DP)拦截规则的作用:

规则配置 未标注污点算子数 运行状态说明
Full Dooly (完整规则) 0 正常,覆盖率 100%
w/o DP (去掉维度保持规则) - 抛出歧义碰撞异常导致追踪失败
w/o DP (强制抑制歧义继续执行) 241 关键算子维度丢失,导致无法正确扫描
w/o DM (去掉维度映射规则) 448 维度来源断裂,严重破坏签名去重准确性

关键发现

  • 注意力算子主导剖析时间与收益:在剖析总节省的 14.98 GPU 小时中,高达 95%(14.24 小时)来自注意力计算的跨模型复用。例如标准 GQA (32/8/128) 结构在 8 款模型中被反复共享,其注意力算子剖析节省率高达 80.4%。
  • 长尾模型迅速饱和:测试表明,仅在剖析前 4 款模型后,算子签名空间就覆盖了全库 98% 的 GPU 剖析耗时,后续 8 款模型平均每款仅需增量运行不到 0.2 GPU 小时。
  • 粗粒度比对导致预测严重失真:若采用配置文件比对(HMD),由于无法识别 Command-R7B 中交织存在的滑动窗口注意力(24 层滑动窗口 + 8 层全注意力),在 32K 提示下预测误差飙升至 37.3%;而 Dooly 将运行时属性融入签名,准确度保持在 4.8%。

亮点与洞察

  • 巧妙将软件工程中的“动态污点分析”迁移至张量推理图分析,精准剥离出张量形状中由“模型静态定义”与“请求动态输入”带来的两类属性,从根本上化解了维度扫描盲目爆炸的问题。
  • 采用非侵入式的“自底向上层次回退 + 运行时上下文复用”,直接利用被测推理引擎自身经过实战检验的初始化逻辑生成元数据,既避免了为每个新型注意力算子手写驱动代码,又保住了端到端模拟的保真度。
  • 算子签名设计充分兼顾了底层编译特征(CUDA Kernel 符号)与模块运行时分支状态(如 sliding window 大小),使不同层混用不同注意力模式的非均匀模型(如 Ministral、Command-R)能够免受哈希混淆。

局限与展望

  • 对于完全绕过 PyTorch Dispatcher 的定制代码段(如手写 Triton 独立外部内核),如果缺乏 Dispatcher 级跟踪,其内部算子无法单独拿到细粒度污点,必须退化至父级 Module 粗粒度剖析,略微损失细粒度去重机会。
  • 目前虽然在文本多模态上表现优异,但在视觉(ViT/VLM)与音频多模态任务上的输入端污点注入规则还需扩展新的请求入口标签。
  • 尽管 source tainting 代码极度紧凑(适配新版引擎通常仅需数行修改),但当服务引擎核心调度数据结构发生颠覆性重构时,仍需微量维护。

相关工作与启发

  • vs Vidur / Revati / LLMServingSim: 现有模拟器依赖针对固定模型和固定引擎编写的算子硬编码模板,跨模型适配成本高昂且算子网格剖析时间随模型数量线性增长;Dooly 实现了全自动算子发现、无配置绑定和跨模型 56%+ 的剖析时间削减。
  • vs llm-d 等分布式调度器: 现代集群级多模型调度框架依赖准确的轻量延迟预估来做路由分发;Dooly 生成的结构化算子库可作为即插即用的共享离线组件,无需对每个实际节点全量评测即可完成异构服务池的秒级延迟预测。

评分

  • 新颖性: ⭐⭐⭐⭐⭐ 首次将动态污点追踪与层次化上下文重构结合引入大模型推理算子剖析,洞察深刻。
  • 实验充分度: ⭐⭐⭐⭐⭐ 覆盖 2 种硬件、3 种主流注意力后端、2 大引擎及 12+ 款架构,数据详实严谨。
  • 写作质量: ⭐⭐⭐⭐⭐ 逻辑推导层次分明,挑战与关键设计的映射关系交代清晰。
  • 价值: ⭐⭐⭐⭐⭐ 极大降低了学术界与工业界探索大模型服务配置空间的算力壁垒,开源实用性极高。