
这次我们来看一个和 AI 编译器、GPU Kernel 高性能优化有关的新方向SparseDitto。简单说这是一个基于 LLM Agent 的智能体系统目标是根据不同的稀疏模式Sparsity Patterns自动生成并定制 GPU Kernel。也就是说不用再针对每一种稀疏结构手工写 CUDA 内核而是让大模型根据算子形状、稀疏格式和硬件信息自动完成代码生成、编译、运行验证和性能调优。这类项目最值得关注的点有三个第一它把 LLM 从“聊天工具”变成了“能写 CUDA 并跑通 benchmark”的工程化 Agent第二它直接面向真实痛点——不同稀疏模式的 Kernel 定制成本极高手工优化周期长第三它天然适合批量化处理可以用一套任务队列同时生成多个 Kernel。如果你关心 GPU 算子自动生成、稀疏计算优化、LLM Agent 与编译器的结合这篇文章值得收藏。下面我会从 SparseDitto 的核心能力、技术原理、本地部署思路、功能测试、API 批量任务、资源占用和常见问题几个维度展开。需要先说明目前公开材料有限文中涉及安装命令、接口示例、参数格式等均以通用模板形式给出实际操作时需要以项目源码和官方文档为准。1. SparseDitto 核心能力速览能力项说明项目类型基于 LLM 的 GPU Kernel 自动生成与定制系统核心技术LLM-Based Agentic System面向稀疏计算主要功能分析稀疏模式、生成 CUDA Kernel、编译验证、性能调优输入稀疏矩阵/算子描述、目标硬件信息、性能约束输出可编译运行的 GPU Kernel 源码、基准测试结果启动方式取决于项目实现通常为命令行或 API 服务是否支持 GPU需要 NVIDIA GPU 环境用于编译和运行验证显存占用与本地 LLM 是否启用、测试矩阵大小、算子复杂度有关需实测是否支持批量任务从 Agent 工作流看适合批量提交多种稀疏模式是否支持 API若项目封装了服务可通过 REST API 提交任务和获取结果适合场景稀疏算子优化、模型推理加速、AI 编译器研究、GPU Kernel 自动生成从表格可以看出SparseDitto 不是一个面向普通文生图/视频的工具而是一个面向开发者和研究者的生产力系统。它的价值在于把“人工分析稀疏格式、手写 CUDA Kernel、手动调参”压缩成“描述需求Agent 自动干活”。2. 技术原理与 Agent 工作流SparseDitto 的设计核心是“Agent 循环”。传统方案里工程师拿到一个稀疏算子后需要先判断它是结构化稀疏、随机稀疏、块状稀疏还是细粒度稀疏然后选择合适的存储格式CSR、CSC、COO、BSR 等再编写 CUDA Kernel最后在真实 GPU 上测试和调优。这套流程非常依赖经验而且每种稀疏模式都对应不同的优化策略。SparseDitto 的思路是把上述流程交给 LLM Agent 自动执行。从标题和当前学术方向来看它的工作流大致可以抽象为解析任务接收用户提交的算子定义、稀疏模式描述、目标 GPU 型号和性能要求。分析稀疏模式通过读取矩阵分布、当前存储格式、非零元素比例等信息判断该选择哪种稀疏策略。生成 Kernel 候选代码LLM 根据分析结果生成 CUDA Kernel 源码可能包含多种候选实现。编译与运行Agent 调用编译器生成可执行文件并在真实 GPU 上执行测试。反馈与迭代把编译错误、运行时间、正确性校验结果反馈给 LLMAgent 根据反馈修改代码再次编译直到满足要求。这种“生成 - 编译 - 运行 - 反馈 - 再生成”的闭环就是 LLM-Based Agentic System 的核心。它不只是生成一段静态代码而是在和真实硬件环境交互。如果要用一个流程表示下面是简化版的 Agent 主循环伪代码实际实现可能更复杂import os import subprocess from typing import Dict, Any # 伪代码示例展示 Agent 工作流骨架 class SparseDittoAgent: def __init__(self, llm_client, compile_cmd: str, run_cmd: str): self.llm_client llm_client self.compile_cmd compile_cmd self.run_cmd run_cmd self.max_iterations 5 def generate_kernel(self, task: Dict[str, Any]) - str: prompt self.build_prompt(task) kernel_code self.llm_client.complete(prompt) return kernel_code def compile_and_run(self, kernel_code: str) - Dict[str, Any]: # 写临时文件、编译、运行 kernel_path /tmp/kernel.cu with open(kernel_path, w, encodingutf-8) as f: f.write(kernel_code) compile_result subprocess.run( self.compile_cmd.format(kernel_pathkernel_path), shellTrue, capture_outputTrue, textTrue, ) if compile_result.returncode ! 0: return {status: compile_error, message: compile_result.stderr} run_result subprocess.run( self.run_cmd, shellTrue, capture_outputTrue, textTrue, ) if run_result.returncode ! 0: return {status: runtime_error, message: run_result.stderr} return {status: ok, output: run_result.stdout} def run(self, task: Dict[str, Any]) - Dict[str, Any]: history [] for _ in range(self.max_iterations): kernel_code self.generate_kernel({**task, feedback: history}) result self.compile_and_run(kernel_code) if result[status] ok: return {success: True, kernel: kernel_code, result: result} history.append(result) return {success: False, history: history}这里的关键点在于LLM 并不是凭空生成一个 Kernel 就结束而是必须通过编译器和运行测试的校验。这种机制能有效减少“看起来对但实际跑不了”的代码输出。从技术难度上看SparseDitto 要解决的问题比“生成一段通用 CUDA 代码”更聚焦。它需要 Agent 理解不同稀疏模式的本质差异比如结构化稀疏如 2:4 稀疏张量中每 4 个元素固定有 2 个非零值适合专用 Tensor Core 指令。块状稀疏Block Sparsity非零元素以块为单位分布适合用 warp-level 协作加载。随机稀疏 / 细粒度稀疏非零元素位置不规则高度依赖索引计算和负载均衡。SparseDitto 真正有价值的地方是让模型学会根据这些差异选择不同的内存访问策略、线程映射方式、共享内存使用方案而不是简单套模板。3. 适用场景与使用边界3.1 适合谁用GPU 高性能计算研发人员日常需要面对各种稀疏算子想减少手写 CUDA 的时间。大模型推理优化工程师模型剪枝、量化后会产生稀疏权重不同层/不同模型稀疏模式不同需要定制 Kernel。AI 编译器研究者关注如何用 LLM 自动化硬件代码生成SparseDitto 是一个很好的实验载体。算法工程师希望快速验证某种稀疏策略在 GPU 上的真实收益而不想陷入底层优化细节。3.2 能解决的问题减少 Kernel 手工开发周期从“几天”压缩到“几小时”。降低跨硬件优化门槛Agent 可以针对不同 GPU 架构生成不同的 Kernel。统一多种稀疏模式可以用一套系统处理结构化、块状、随机等多种稀疏格式。便于批量优化面对一个稀疏矩阵库可以用批量任务逐一生成 Kernel。3.3 不适合什么场景面向普通用户的一键型工具SparseDitto 面向开发者需要命令行和编译环境。对性能要求极其苛刻的生产场景Agent 生成的 Kernel 可能仍需要人工 review 和进一步调优不能直接当作最终上线的唯一依据。没有 GPU 环境的环境如果本机没有 NVIDIA GPU则无法完成编译运行验证环节。3.4 使用边界与合规提醒使用 SparseDitto 时需要注意以下几点仅用于自己拥有合法授权或公开可用的模型权重、稀疏矩阵和测试数据。如果要将生成的 Kernel 用于商业产品需要确认相关开源代码和模型权重的许可协议。涉及第三方专有稀疏格式或专利算法时不要直接复制实现需要了解专利和授权边界。生成代码可能包含未预期的内存访问务必在隔离的测试环境运行不要直接在生产集群跑未验证的 Kernel。如果需要调用远端 LLM API 来驱动 Agent注意不要上传包含敏感信息的内部矩阵或数据集避免数据扩散。4. 环境准备与前置条件SparseDitto 的核心链路是“LLM 生成代码 - GPU 编译运行”。因此环境准备分为两部分一部分是生成代码所需的 LLM 推理环境另一部分是编译运行 GPU Kernel 所需的 CUDA 工具链。4.1 硬件要求GPU建议使用 NVIDIA GPU支持 CUDA。具体算力版本需要根据项目支持情况确认。显存如果 Agent 使用本地 LLM则需要额外考虑 LLM 推理显存占用如果使用云端 LLM API本地显存主要用于矩阵测试和 Kernel 运行。内存编译大型 CUDA Kernel 时内存要充足建议 16GB 以上。磁盘CUDA Toolkit、编译器、测试数据集、缓存文件会占用较多空间建议预留 20GB 以上。4.2 软件依赖以下是一个通用检查清单实际依赖需要以项目 README 为准Ubuntu 20.04 或更高版本或其他支持 CUDA 的 Linux 发行版。NVIDIA 驱动 CUDA Toolkit例如 11.8 或 12.x。Python 3.9用于运行 Agent 任务脚本。PyTorch如果项目需要做算子正确性对比。代码生成所需的 LLM 客户端OpenAI API、本地 VLLM/Ollama 等任选其一。编译工具链g、nvcc、Make/CMake。4.3 验证 CUDA 环境启动任何任务前先确认 GPU 驱动和 CUDA 编译器可用# 检查 GPU 是否被系统识别 nvidia-smi # 检查 CUDA 编译器版本 nvcc --version # 检查 Python 版本 python3 --version如果nvidia-smi正常输出说明驱动正常。如果nvcc --version提示找不到命令需要安装 CUDA Toolkit。编译 CUDA Kernel 时版本不匹配是高频问题务必保持驱动版本和 Toolkit 版本兼容。5. 安装部署与启动方式由于 SparseDitto 的公开源码仓库和安装脚本尚未在本次输入材料中明确给出下面给出一套通用的部署思路。等实际仓库公开后以官方 README 为准。5.1 获取代码通常这类项目会通过 Git 发布git clone https://github.com/your-org/SparseDitto.git cd SparseDitto这里your-org需要替换为实际仓库地址。如果项目已经在 PyPI 发布也可以尝试pip install sparseditto5.2 创建虚拟环境推荐使用 conda 或 venv 隔离依赖python3 -m venv sparseditto-env source sparseditto-env/bin/activate pip install --upgrade pip pip install -r requirements.txt如果项目中包含自定义 CUDA 扩展可能还需要执行python setup.py build_ext --inplace5.3 配置 LLM 客户端SparseDitto 的 Agent 需要一个 LLM 后端。具体配置方式取决于项目实现但常见形式是环境变量或配置文件# 使用 OpenAI 兼容接口的示例 export LLM_API_KEYyour-api-key export LLM_BASE_URLhttps://api.your-llm-provider.com/v1 export LLM_MODELyour-model-name如果使用本地模型则需要提前启动一个 OpenAI 兼容的推理服务例如 vLLM 或 Ollama。然后在配置中把base_url指向本地地址。5.4 启动一个 Kernel 生成任务假设项目提供一个命令行入口可能的形式如下python -m sparseditto.run \ --task-config ./tasks/sparse_2_4.json \ --output-dir ./outputs \ --gpu 0其中sparse_2_4.json是一个任务描述文件内容可能包括矩阵尺寸、稀疏模式、目标硬件和性能要求。下面是一个通用模板{ task_name: sparse_2_4_example, matrix_size: [4096, 4096], sparsity_pattern: structured_2_4, nonzero_ratio: 0.5, target_gpu: A100, performance_target_ms: 1.0, compile_flags: [-O3, -archsm_80] }实际项目可能使用自己的输入格式。如果你拿到的版本支持交互式模式也可以直接通过 Python API 提交任务。5.5 启动 API 服务如果 SparseDitto 提供 HTTP 服务常见启动方式如下python -m sparseditto.server --host 127.0.0.1 --port 8000启动后可以通过 REST API 提交 Kernel 生成任务。具体接口路径需要查阅项目文档下面第六节会给出通用调用示例。6. 功能测试与效果验证SparseDitto 的核心功能是生成可运行且性能合理的 GPU Kernel。因此测试应该围绕三个维度展开正确性、可编译性、性能。6.1 测试目标能根据不同的 Sparsity Patterns 生成 Kernel。生成代码能通过编译。Kernel 运行结果和参考实现一致。Kernel 性能优于或接近手工基线。6.2 测试用例设计建议准备多组稀疏模式覆盖典型场景2:4 结构化稀疏。块状稀疏例如 128x128 块。随机稀疏非零元素均匀分布。细粒度稀疏非零元素比例极低。每个用例可以包含矩阵大小、稀疏比例、迭代次数。如果项目支持正确性校验可以将输出与 PyTorch 稀疏算子结果对比。6.3 正确性测试思路假设 Agent 输出一个 Kernel 文件sparse_kernel.cu我们可以用以下通用流程验证编译 Kernel 成可执行文件或动态库。准备输入稀疏矩阵。分别调用待测 Kernel 和参考实现如 cuSPARSE 或 PyTorch。对比输出矩阵的数值误差。一个通用验证脚本结构如下import numpy as np import torch import subprocess # 这里只展示验证流程骨架需要按实际 Kernel 接口调整 def run_kernel(input_matrix) - np.ndarray: # 调用编译好的 Kernel例如通过 PyTorch 扩展加载 # 这里用 subprocess 举例 proc subprocess.run( [./sparse_kernel, --input, input.npy, --output, output.npy], capture_outputTrue, textTrue, ) if proc.returncode ! 0: raise RuntimeError(proc.stderr) return np.load(output.npy) def reference_implementation(input_matrix) - np.ndarray: # 使用 PyTorch 稀疏矩阵乘法作为参考 # 这里仅作示例实际参考实现取决于算子类型 return input_matrix.to_dense().numpy() input_sparse torch.rand((2048, 2048)).to_sparse() expected reference_implementation(input_sparse) actual run_kernel(input_sparse) if np.allclose(expected, actual, rtol1e-3, atol1e-5): print(正确性验证通过) else: print(正确性验证失败请检查 Kernel 实现)这里的验证逻辑非常关键。如果 Kernel 输出结果和参考实现差距过大说明 Agent 生成的代码存在逻辑错误需要反馈给 Agent 重新迭代。6.4 性能测试思路性能测试要关注两个维度单次 Kernel 延迟。不同稀疏模式下的性能差异。建议为每种稀疏模式运行多次取平均耗时。还可以对比不同 Kernel 实现Agent 生成的多种候选。如果项目支持性能自动反馈Agent 会自行选择最优候选。6.5 测试通过标准编译通过率在给定用例上超过一定比例的稀疏模式能被成功编译。正确性输出误差满足容差范围。性能相比 baseline 有一定提升或者至少达到用户设定的延迟目标。注意具体通过标准需要根据项目 README 和用户需求调整不要一概而论。7. 接口 API 与批量任务SparseDitto 最有工程价值的一点是它可以被封装成 API 服务通过批量任务处理多种稀疏模式。如果你有一个模型库里面有 50 个稀疏矩阵不同层稀疏模式不同手工调 Kernel 会非常耗时但用 Agent 批量跑只需要提交 50 个任务然后收集结果。7.1 通用 API 调用示例假设项目提供/api/generate_kernel接口请求形式可能如下import requests import time API_URL http://127.0.0.1:8000/api/generate_kernel payload { task_name: bert_attention_sparse, matrix_size: [4096, 4096], sparsity_pattern: block_sparse, block_size: [64, 64], nonzero_ratio: 0.2, target_gpu: A100, max_iterations: 5, callback_url: http://127.0.0.1:9000/callback } response requests.post(API_URL, jsonpayload, timeout10) print(response.status_code) print(response.json())同步模式下响应里可能包含生成的 Kernel 代码、编译结果、耗时和性能数据。异步模式下请求会先返回一个task_id之后轮询任务状态TASK_ID response.json()[task_id] while True: status_resp requests.get(f{API_URL}/status/{TASK_ID}, timeout10) status status_resp.json() if status[status] in (success, failed): print(status) break time.sleep(3)7.2 批量任务队列设计批量任务需要有一个清晰的任务队列。推荐结构输入目录存放所有稀疏模式描述文件。任务队列每个文件对应一个任务。结果目录按任务名保存生成的 Kernel、编译日志、运行日志。失败重试如果 Agent 迭代多次仍失败可以自动记录失败原因稍后统一处理。一个批量任务配置示例{ batch_name: layer_sparsity_test, input_dir: ./tasks, output_dir: ./results, gpu_ids: [0, 1, 2, 3], max_concurrent: 4, retry_count: 1 }执行时可以用 Python 脚本遍历任务目录逐个提交。由于 Agent 任务可能涉及多次编译建议避免无限并发控制在 GPU 显存能承受的范围内。7.3 失败重试建议编译失败可以自动把错误信息加到 Prompt 中让 Agent 尝试修复最多重试 N 次。运行超时给每个 Kernel 设置超时时间防止死循环占用 GPU。显存不足减小测试矩阵规模或等待其他任务结束后再执行。进程崩溃以任务文件为单位做断点续跑记录已完成的任务 ID。8. 资源占用与性能观察运行 SparseDitto 时资源占用主要来自三个部分LLM 推理、Kernel 编译、Kernel 运行验证。这三部分的资源特征不同需要分别观察。8.1 LLM 推理资源占用如果使用云端 LLM API本地不占用额外显存但会依赖网络和 API 调用的 token 配额。如果使用本地 LLM例如 7B 模型生成 Kernel 时可能占用 6GB-16GB 显存具体取决于量化方式和上下文长度。本地 LLM 推理还会增加每轮迭代的延迟Agent 的迭代次数越多耗时越长。8.2 编译与验证资源占用编译 CUDA Kernel 时CPU 和内存占用较高。运行 Kernel 测试时显存占用取决于测试矩阵大小和 Kernel 内部临时缓冲区。如果测试矩阵是 4096x4096 的 float32 稀疏矩阵显存占用通常不高但如果是大尺寸稠密中间结果显存可能暴涨。建议使用nvidia-smi周期性记录显存占用# 每 2 秒记录一次显存信息 watch -n 2 nvidia-smi如果想要精确记录可以用nvidia-smi --query-gpumemory.used,utilization.gpu --formatcsv -l 2。8.3 影响性能的关键维度稀疏模式复杂度随机稀疏比结构化稀疏更难生成高效 KernelAgent 迭代次数可能更多。目标 GPU 架构不同架构需要不同的向量化和共享内存策略Agent 生成的候选代码差异明显。编译优化等级-O3与-O2、-arch参数会影响 Kernel 性能。LLM 模型能力模型越强生成的初始代码质量越高迭代次数越少。8.4 如何降低资源占用优先使用云端 LLM API减少本地显存压力。控制 Agent 的最大迭代次数例如 3-5 次避免无限循环。先用小规模矩阵做正确性测试通过后再跑大规模性能测试。批量任务时控制并发度避免多个 Kernel 同时编译导致内存耗尽。及时清理临时 CUDA 文件避免磁盘被日志占满。9. 常见问题与排查方法问题现象可能原因排查方式解决方案Agent 生成代码无法编译nvcc 版本不支持语法或缺少头文件查看编译日志中的具体错误将编译错误反馈给 Agent 自动修复或调整 CUDA 版本Kernel 运行结果不正确索引计算错误、共享内存越界、没有同步对比参考实现逐段检查 Kernel让 Agent 重新生成重点提示错误类型显存不足OOM测试矩阵过大或 Kernel 临时缓冲区过大使用nvidia-smi查看显存变化缩小矩阵尺寸或优化 Kernel 内存申请LLM API 调用失败网络不通、API key 错误、token 超限先单独测试 LLM 客户端检查环境变量和网络确认模型服务可用批量任务卡住某个 Kernel 编译卡死或运行死循环查看任务日志定位卡住的任务设置编译和运行的超时时间启动服务后端口被占用默认端口已被其他进程使用使用lsof -i :8000检查修改--port参数Agent 迭代多次仍失败任务描述不清晰或 LLM 无法理解稀疏模式检查任务 JSON 是否缺少关键字段补充稀疏格式、矩阵尺寸、硬件信息简化任务描述性能始终无法达到目标稀疏模式本身限制或 LLM 生成的 Kernel 策略不对对比手工 baseline 的耗时尝试不同 LLM 模型或增加性能反馈的细节在实际使用过程中最需要重视的是“日志可观测性”。SparseDitto 作为一个 Agent 系统它每次生成、编译、运行、反馈都应该有日志记录。这样无论是排查问题还是复现实验结果都能找到依据。9.1 日志建议建议在任务管理中加入以下日志generation/{task_id}.prompt每次发送给 LLM 的 Prompt。generation/{task_id}.responseLLM 返回的 Kernel 代码。compile/{task_id}.log编译日志。run/{task_id}.log运行日志。result/{task_id}.json最终结果和性能数据。9.2 如何判断结果是否可信不要只看单个 Kernel 的测试结果。建议相同任务至少执行 3 次取抖动最小的数据。同时要检查 Kernel 是否真正在目标 GPU 上运行有些环境可能会误用 MIG 实例或虚拟化 GPU导致性能数据失真。对于自动生成的 Kernel发布到生产环境前需要人工 review 关键内存访问逻辑。在多个矩阵规模上做回归测试。对比 cuSPARSE 等成熟库的性能确认收益真实存在。保留测试输入和输出方便后续追踪。最后一点实践建议SparseDitto 这类 LLM Agent 系统真正落地时拼的不是“能不能生成代码”而是“能不能稳定地生成可用的代码”。如果你打算在自己的机器上尝试建议从最简单的稀疏模式开始先用小矩阵验证流程再逐步增加复杂度。最容易踩的坑是一开始就提交一个巨大的随机稀疏矩阵任务结果 Agent 不断编译失败或者生成了能跑但极慢的 Kernel这时候你很难判断是 LLM 能力问题、任务描述问题还是环境问题。正确的路线是先跑通“生成 - 编译 - 运行 - 正确性对比”的最小闭环确保你的 CUDA 环境、LLM 客户端、任务描述格式都正常然后才开始挑战不同 Sparsity Patterns 的性能优化。把 SparseDitto 当成一个自动调优助手而不是完全替代工程师的“代码生成器”它的价值会更稳定。后续你可以继续关注Agent 是否支持多 GPU 调度、是否能自动选择最优稀疏存储格式、是否能与 PyTorch/TVM/MLIR 编译栈集成。如果这些方向都成熟SparseDitto 完全有机会成为 AI 编译器工具链里一个重要的自动化组件。建议把本文收藏等官方仓库和文档发布后按照这里的部署思路和测试方法快速上手。