FEATURED · 精选文章

tinygrad 请求链路中间件开发:从 UOp 图到 PatternMatcher 与 TinyJit 完整指南

发布时间 / 2026/9/2 14:36:59
来源 / 创域科博编辑部
栏目 / 资讯中心
tinygrad 请求链路中间件开发:从 UOp 图到 PatternMatcher 与 TinyJit 完整指南 tinygrad 请求链路中间件开发从 UOp 图到 PatternMatcher 与 TinyJit 完整指南【免费下载链接】tinygradYou like pytorch? You like micrograd? You love tinygrad! ❤️项目地址: https://gitcode.com/GitHub_Trending/tiny/tinygradtinygrad 的架构像一个洋葱模型Tensor 前端、UOp 图、调度器、lowering 引擎、runtime每一层都能被拦截和替换。想在请求经过框架时插入自定义逻辑调度器里可以挂 PatternMatcher 规则JIT 可以缓存整个执行子图UOp 改写也可以挂任意 pattern。这套机制就是 tinygrad 的中间件层本文带你走完整个链路。 为什么说 tinygrad 天生适合插中间件前面提到 docs/developer/developer.md 把框架拆成四块前端、调度器、lowering 引擎、运行时。前端只是 UOp 图的语法糖Tensor 操作会被拆成一个个小节点调度器把大图切成一个个 kernel 调用lowering 把每个 kernel 编译成可执行代码runtime 负责把代码派发到具体设备。这套结构意味着每一段代码都是可拦截的前端到图之间有改写阶段图到 kernel 之间有调度阶段kernel 到设备之间有 runtime 阶段。其他常见框架的图叠在 cuDNN、cuBLAS 等固定 kernel 库上你只能选tinygrad 直接生成 kernel任何一段计算都可以被你的代码改写成别的形状。️ UOp 图理解 tinygrad 请求的载体每个节点是一个四元组(op, dtype, src, arg)定义见 tinygrad/uop/m UOp(Ops.MUL, dtypes.float, src(a, b), argNone)op决定这个节点做什么src是输入节点的列表指向上游arg携带参数例如 kernel 名、常量值节点分 base 和 view 两类base 真正占用 bufferview 只是切出来的视图不额外占内存。这张图不可变所以改写就等于匹配一个子图替换成另一个子图——这正是中间件最擅长干的事。 PatternMatchertinygrad 的核心中间件PatternMatcher 定义在 tinygrad/uop/ops.py本质是一张规则表。每条规则三件事一个要 match 的子图、一个用来 replace 的子图、可选的 guard 条件。框架反复扫全图每匹配一次就替换一次直到没有变化为止。from tinygrad.uop.ops import PatternMatcher, UOp, Ops, dtypes pm PatternMatcher([ (UOp(Ops.MUL, src(UOp.variable(a), UOp.const(1.0))), lambda ctx, a: UOp(Ops.ADD, src(a, a))), ]) new_graph graph_rewrite(sink, pm, namemy_middleware)上面这条规则做的事情a * 1.0改写成a a。你可以把自定义规则塞进调度阶段或 lowering 阶段就像在中间件链里加一个环节框架原有的 beam 搜索优化、内存规划本身也是同一套 PatternMatcher 规则。⚡ TinyJit把整个请求打包成一次回放TinyJit 是请求级中间件包一层函数让它跑三次就稳定下来。from tinygrad.engine.jit import TinyJit TinyJit def train_step(x, target): loss model(x).sparse_categorical_crossentropy(target) return loss.backward()第一次调用走原函数当作热身第二次捕获这次执行产生的全部 kernel 调用合并成一个大 LINEAR交给调度器重新做内存规划、再编译支持 graph 的设备还会把多个 kernel 打包成一次 graph launch从第三次开始就不再走 Python 前端了只替换输入 buffer直接执行已经编译好的东西。JIT0关闭JIT2升级到更激进的 graph 批量。 用 VIZ 与 DEBUG 观察请求被谁改写了打开两个环境变量就能看到整条链路的执行轨迹VIZ1打开可视化窗口每一次graph_rewrite的中间快照都能回放PatternMatcher 支持 trace 参数追踪每条规则命中几次DEBUG2在终端打印调度器的拆分结果和 JIT 捕获了多少 kernel跑一遍 test/test_tiny.py 或 examples/beautiful_mnist.py你能完整看到一次请求在每个中间件阶段经历了什么。⚠️ 新手最容易踩的四个坑JIT 输入必须是真实 buffer。传视图或切片进去会抛JIT inputs must be real buffers; use .clone()先.clone()再传。同一个张量不能当两个输入。会直接抛duplicate inputs to JIT。TinyJit 里不能再套 TinyJit。捕获阶段会抛RuntimeError嵌套结构要拆层。PatternMatcher 规则要写成幂等的否则会反复触发框架有迭代上限保护但你的规则最好在replace后不再匹配自己。这四个坑都有对应的异常类型和测试用例报错信息通常能直接指向问题建议读一遍 test/test_uops.py 和 test/null/test_pattern_matcher.py。下一步做什么三件事按顺序做就行用DEBUG2跑一遍 examples/beautiful_mnist.py先看清每个请求在哪一层被拦截。打开VIZ1在浏览器里逐帧看 UOp 图的改写过程找到原来这条规则在这里生效的直观感受。挑一个你感兴趣的优化阶段tinygrad/codegen/ 里按 simplify、opt、decomp、late 分层写一条自己的 PatternMatcher 规则跑通现有测试。做到第三步tinygrad 就从你用的框架变成你能改的框架。【免费下载链接】tinygradYou like pytorch? You like micrograd? You love tinygrad! ❤️项目地址: https://gitcode.com/GitHub_Trending/tiny/tinygrad创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻