【TVM教程】Pass 基础设施

TVM前端研究--Pass 在 TVM 中,Pass 根据 IR 类型的不同分为 Relay 上的优化和 TIR 上的优化。因此,Relay 上的 Pass 包括通用的 pass,在 tvm.relay.transform 目录下,还有一些 Pass 包含系统信息或后端信息,在其他目录下如 AnnotateUsedMemory Pass 等。是包含了一个 Pass 所需的基本信息如 name 是 pass 名称,opt_level 表示将在哪个优化级别启用 pass,required 表示执行某个 pass 所需的 pass。 阅读详情

TVM 现已更新到 0.21.0 版本,[TVM 中文文档]已经和新版本对齐。

Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →[Apache TVM]

在线运行 TVM 学习教程

链接是:https://hyper.ai/notebooks/48919?utm_source=Distribute&utm_medium=Distribute-TVM&utm_campaign=Distribute-TVM-260126

Relax 与 TVM IR 都包含一系列优化传递(optimization passes),用于改进模型在特定设备上的性能指标,例如推理平均时间、内存占用或功耗。这些优化包括标准优化与机器学习特定优化,如常量折叠(constant folding)、死代码消除、算子布局变换、算子融合、缓冲区处理和循环变换等。每个传递都是基于收集的分析结果进行的 IR-to-IR 转换。

然而,随着 TVM 的快速发展,越来越需要一种系统化且高效的方式来管理这些传递。此外,一个通用的框架能够在 TVM 栈的不同层次(例如 Relax 和 tir)之间管理传递,这为开发者快速原型化和集成新传递铺平了道路。

本文档介绍了这种基础设施的设计,它结合了生产级编译器中用于管理优化传递的方式,以及现代深度学习框架用于构建层次化结构的风格。

例如,许多现有的生产级编译器(如 GCC 与 LLVM) 采用「传递管理器(pass manager)」来高效管理传递执行。最初传递数量较少时管理很简单,但成熟编译器可能包含数百个独立传递。外部用户往往希望添加自定义传递,并能正确调度,而无需手动修改固定顺序。

类似地,现代深度学习框架(如 Pytorch 与 MXNet Gluon)也倾向于通过Sequential和Block实现类似「传递式」层构建机制。 借助这些构造,框架能够轻松将模块或层添加到容器中,从而快速搭建神经网络。

TVM 的传递基础设施设计灵感主要来自 LLVM 的层次化传递管理器 以及流行深度学习框架的模块化容器。 该系统的主要目标包括:

  1. 支持更灵活的优化编排,让用户能自由构建自定义优化流水线。
  2. 提供便捷的调试机制。
  3. 让开发者无需手动解决传递之间的依赖。
  4. 简化新传递的实现方式,例如允许用户直接用 Python 实现一个传递,由系统自动管理其执行。

设计概述​

系统重点关注可扩展性,使用户能快速添加新传递而不破坏兼容性。 其结构包括后端与前端:后端实现核心逻辑,前端则提供简单的 API 供用户创建与控制优化流程。

C++ 后端​

我们提供 PassInfo对象来存储单个传递所需的基本信息:name为传递名,opt_level指示该传递在哪个优化级别启用,required表示执行该传递前所需的其他传递(详见include/tvm/ir/transform.h)。 在注册传递时,开发者可以指定传递名称、优化级别与依赖。 opt_level可帮助系统在给定优化级别下判断某个传递是否需要执行; required字段用于自动解析传递依赖。

class PassInfoNode : public Object {
  ffi::String name;
  int opt_level;
  ffi::Array<ffi::String> required;
};
PassContext​

PassContext 携带优化传递所需的关键信息。例如,它包含错误报告系统,方便优化作者诊断失败原因。 PassContext也取代了旧的 BuildConfig(用于配置编译选项,如优化级别、必需/禁用传递等)。例如,我们可以配置在 opt_level=3 下执行所有传递,并通过disabled_pass=xx 禁用某些传递;系统会聚合该级别的所有传递并排除被禁用的项。PassContext还提供对所有传递进行"检测(instrumentation)"的能力,见 pass_instrument_cpp_backend。

该类支持 Python with 语法,便于在给定配置下执行优化。 同时,用户可以通过 PassContext::Current()在线程安全的方式获取当前上下文, 因为系统使用线程本地存储PassContextThreadLocalStore 来保存上下文对象。

class PassContextNode : public Object {
 public:
  int opt_level{2};
  tvm::ffi::Array<tvm::Expr> required_pass;
  tvm::ffi::Array<tvm::Expr> disabled_pass;
  mutable ffi::Optional<DiagnosticContext> diag_ctx;
  ffi::Map<ffi::String, Any> config;
  ffi::Array<instrument::PassInstrument> instruments;
};

class PassContext : public NodeRef {
 public:
  TVM_DLL static PassContext Create();
  TVM_DLL static PassContext Current();
  TVM_DLL void InstrumentEnterPassContext();
  TVM_DLL void InstrumentExitPassContext();
  TVM_DLL bool InstrumentBeforePass(const IRModule& mod, const PassInfo& info) const;
  TVM_DLL void InstrumentAfterPass(const IRModule& mod, const PassInfo& info) const;
  /* 其他字段省略 */

 private:
  // 进入 pass 上下文作用域
  TVM_DLL void EnterWithScope();
  // 离开 pass 上下文作用域
  TVM_DLL void ExitWithScope();

  // 用于支持 Python `with` 语法
  friend class tvm::With<PassContext>;
};

struct PassContextThreadLocalEntry {
  /*! rief 默认 pass 上下文 */
  PassContext default_context;
  /*! rief 当前 pass 上下文 */
  std::stack<PassContext> context_stack;
  PassContextThreadLocalEntry() {
    default_context = PassContext(make_node<PassContextNode>());
  }
};

/*! rief 线程本地存储,用于保存 pass 上下文 */
typedef dmlc::ThreadLocalStore<PassContextThreadLocalEntry>
     PassContextThreadLocalStore;
Pass 构造​

传递(Pass)基础设施以分层结构设计,可在 Relax/tir 程序的不同粒度上工作。 系统定义了一个纯虚类PassNode,作为各种优化传递的基类。此类包含多个必须在子类中实现的虚函数,适用于模块级、函数级或顺序传递级别。

class PassNode : Object {
  virtual PassInfo Info() const = 0;
  virtual Module operator()(const IRModule& mod,
                            const PassContext& pass_ctx) const = 0;
};

该函数对象定义了传递的执行方式: 每个传递都在特定上下文 PassContext下作用于一个 IRModule, 并以 Module 到 Module 的方式实现。因此,所有传递都以模块为单位更新整个 IR。

系统实现了多个 PassNode 子类来支持不同类型的优化: 包括函数级传递、模块级传递与顺序传递(sequential pass)。 每个子类本身都可充当一个传递管理器,例如:它们可以收集所需传递并执行,或基于元信息建立依赖图。完整定义见src/ir/transform.cc。

模块级传递​

模块级传递主要用于全局或过程间优化(IPO),类似于 LLVM 中的模块传递。Relax 中一些典型需要全局视图的优化(如 A-normal form 转换、lambda 提升)就属于此类。 在该级别,用户可以在模块中添加或删除函数。

class ModulePassNode : PassNode {
  PassInfo pass_info;
  std::function<Module(Module, PassContext)> pass_func;
  Module operator()(const Module& mod, const PassContext& pass_ctx) const final;
  // 其他成员/方法省略
};

pass_info 存储模块传递的相关信息,pass_func 定义实际优化逻辑。例如,在模块上执行死代码消除可在 pass_func 中实现,它将删除模块中未使用的函数。 此字段被设计为「打包函数(packed function)」, 因此优化逻辑既可用 C++ 实现,也可用 Python 实现。

函数级传递​

函数级传递用于实现 Relax/tir 模块中函数内的优化。它一次提取模块中的一个函数进行优化,输出优化后的 Relax Function 或 tir PrimFunc。多数优化都属于此类,如 Relax 的公共子表达式消除、推理简化,或 tir 的向量化与内存扁平化。

函数级传递仅作用于单个函数(Relax 或 tir),因此无法通过此类传递添加或删除函数,因为其不具备全局信息。

class FunctionPassNode : PassNode {
  PassInfo pass_info;
  std::function<Function(Function, Module, PassContext)> pass_func;
  Module operator()(const Module& mod, const PassContext& pass_ctx) const final;
  bool SkipFunction(const Function& func) const;
  // 其他成员/方法省略
};

pass_info 与模块级传递相同。 pass_func接受函数与模块作为输入,可在函数上执行优化; 函数若被注解为SkipOptimization,将被跳过。

顺序传递(Sequential Pass)​

SequentialPass 类似于 PyTorch 的 nn.Sequential,可包含多个顺序执行的传递。

class SequentialPassNode : PassNode {
  PassInfo pass_info;
  // 需要执行的传递列表
  ffi::Array<Pass> passes;
  bool PassEnabled(const PassInfo& info) const;
  Module operator()(const Module& mod, const PassContext& pass_ctx) const final;
};

以下展示顺序传递的执行逻辑:系统会按照传递添加的顺序依次执行。

Module SequentialNode::operator()(const Module& module,
                                  const PassContext& pass_ctx) const {
  Module mod = module;
  for (const Pass& pass : passes) {
    ICHECK(pass.defined()) << "Found undefined pass for optimization.";
    const PassInfo& pass_info = pass->Info();
    if (!PassEnabled(pass_info))  continue;
    for (const auto& it : pass_info->required) {
      const auto* name = it.as<tvm::ir::StringImm>();
      ICHECK(name);
      mod = GetPass(name->value)(mod, pass_ctx);
    }
    mod = pass(mod, pass_ctx);
  }
  return mod;
}

在执行传递前,系统会判断该传递是否启用:首先检查是否被用户禁用,其次查看是否被显式声明为必需。若仍未确定,则根据 opt_level 判断是否执行。

执行时,系统会根据传递名从注册表中获取对应实现:

Pass GetPass(const std::string& pass_name) {
  using tvm::runtime::Registry;
  std::string fpass_name = "relax.transform." + pass_name;
  const std::optional<tvm::ffi::Function> f = tvm::ffi::Function::GetGlobal(fpass_name);
  ICHECK(f.has_value()) << "Cannot find " << fpass_name
                        << "to create the pass " << pass_name;
  return (*f)();
}

系统还提供辅助函数用于创建各类传递,并暴露给 Python 前端:

Pass CreateFunctionPass(
    std::function<Function(Function, IRModule, PassContext)> pass_func,
    int opt_level,
    ffi::String name,
    ffi::Array<ffi::String> required);

Pass CreatePrimFuncPass(
    std::function<PrimFunc(PrimFunc, IRModule, PassContext)> pass_func,
    int opt_level,
    ffi::String name,
    ffi::Array<ffi::String> required);

Pass CreateModulePass(
    std::function<IRModule(IRModule, PassContext)> pass_func,
    int opt_level,
    ffi::String name,
    ffi::Array<ffi::String> required);

Pass Sequential(tvm::ffi::Array<Pass> passes, PassInfo pass_info);
传递注册​

前文介绍了不同粒度的传递和编译上下文。 下面展示如何注册一个传递。以常量折叠(constant folding)为例, 它用于在 Relax 函数中折叠常量(实现位于 src/relax/transforms/fold_constant.cc)。

该传递提供了 Expr 到 Expr 的转换 API:

Expr FoldConstant(const Expr& expr);

要将其注册到传递基础设施中,首先需要确定传递的粒度。常量折叠作用于函数级,因此通过 CreateFunctionPass 创建:pass_func 以打包函数形式返回,用于对 [IRModule]{.title-ref} 中的每个函数调用该转换 API。 {} 表示该传递没有前置依赖;若有依赖,开发者需明确列出。

同时,注册名为 "relax.transform.FoldConstant" 的 API 入口,使该传递可被 C++ (例如以上的 GetPass )与 Python 访问:

namespace transform {

Pass FoldConstant() {
  auto pass_func =
      [=](Function f, IRModule m, PassContext pc) { return ConstantFolder::Fold(f, m); };
  return CreateFunctionPass(pass_func, 0, "FoldConstant", {});
}

TVM_FFI_STATIC_INIT_BLOCK() {
  namespace refl = tvm::ffi::reflection;
  refl::GlobalDef().def("relax.transform.FoldConstant", FoldConstant);
}

}  // namespace transform

为方便其他 C++ 模块调用,在include/tvm/relax/transform.h中声明:

TVM_DLL Pass FoldConstant();
传递检测(Pass Instrument)​

传递检测机制用于分析传递本身,例如统计执行时间与内存占用,或观察 IR 如何被改变。

我们在 PassContext 生命周期中引入四个检测点:

TVM_DLL void InstrumentEnterPassContext();
TVM_DLL void InstrumentExitPassContext();
TVM_DLL bool InstrumentBeforePass(const IRModule& mod, const PassInfo& info) const;
TVM_DLL void InstrumentAfterPass(const IRModule& mod, const PassInfo& info) const;

InstrumentEnterPassContext 在进入 PassContext 作用域时调用。

InstrumentExitPassContext 在离开 PassContext 或执行发生异常时调用。当通过 :pytvm.transform.PassContext的override_instruments 覆盖检测器时也会触发,见pass_instrument_overriden。

InstrumentBeforePass 在传递执行前调用; 若该传递应执行,则在执行后调用 InstrumentAfterPass。其伪代码如下:

if (pass_ctx.InstrumentBeforePass(ir_module, pass_info)) {
  new_ir_module = run_pass(ir_module, pass_ctx);
  pass_ctx.InstrumentAfterPass(new_ir_module, pass_info);
  return new_ir_module;
}

PassInstrument接口允许你在上述四个阶段插入自定义逻辑。 可向单个PassContext 注册多个检测器实例,它们将按 instruments指定的顺序依次调用。

接口定义如下:

namespace instrument {

class PassInstrumentNode : public Object {
 public:
  ffi::String name;
  virtual void EnterPassContext() const = 0;
  virtual void ExitPassContext() const = 0;
  virtual bool ShouldRun(const IRModule& mod, const transform::PassInfo& info) const = 0;
  virtual void RunBeforePass(const IRModule& mod, const transform::PassInfo& info) const = 0;
  virtual void RunAfterPass(const IRModule& mod, const transform::PassInfo& info) const = 0;
  /* 其他字段省略 */
};

class PassInstrument : public ObjectRef {
 public:
  TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(PassInstrument, ObjectRef, PassInstrumentNode);
};

}  // namespace instrument

Python 前端提供了便捷方式来实现 PassInstrument,见pass_instrument_py_frontend。

在一个 PassContext 中,某个 PassInstrument 实例的调用顺序如下:

with PassContext(instruments=[pi])  # pi 为某个 PassInstrument 实现
    pi.EnterPassContext()

    if pi.ShouldRun(Pass1):
        pi.RunBeforePass()
        Pass1()
        pi.RunAfterPass()

    if pi.ShouldRun(Pass2):
        pi.RunBeforePass()
        Pass2()
        pi.RunAfterPass()

    pi.ExitPassContext()

以下简述 PassInstrument 与 PassContext 方法之间的关系,详见 src/ir/transform.cc:

  • InstrumentEnterPassContext

    • EnterPassContext() 按传入 instruments 的顺序执行。
    • 若执行中抛出异常,PassContext 会清空所有已注册的检测器。
    • 然后对已成功执行 EnterPassContext() 的检测器依次调用 ExitPassContext()。
    • 例如,注册了 A、B、C 三个检测器,A 成功,B 抛异常,则 C 不会执行;随后调用 A 的 ExitPassContext()。
  • InstrumentExitPassContext

    • 各检测器的 ExitPassContext() 按 instruments 顺序执行。
    • 若发生异常,instruments 会被清空。
    • 抛出异常后注册的检测器不会执行 ExitPassContext。
  • InstrumentBeforePass

    • 若该传递未被显式列为"必需",则会调用 ShouldRun。
    • 若未被 ShouldRun 阻塞,则按顺序调用 RunBeforePass。
    • 该函数返回布尔值,指示该传递是否应执行。
    • 若发生异常,将立即抛出;Python 依靠上下文管理器安全退出(确保各检测器的 ExitPassContext 被调用;C++ 见 include/tvm/support/with.h)。
  • InstrumentAfterPass

    • 按顺序调用 RunAfterPass。
    • 若发生异常,将立即抛出;依靠上下文管理器或 With 类(include/tvm/support/with.h)安全退出。
内置检测器​

系统内置若干检测器(标注 TODO 的尚未实现):

  • PassTimingInstrument(见 src/ir/instrument.cc)

    • 用于分析各传递的执行时间。
  • PrintIRBefore(TODO)

    • 在传递执行前打印 IR。也可通过 :pytvm.transform.PrintIR{.interpreted-text role=“func”} 在传递周围插入打印实现;但使用检测器无需修改传递序列。
  • PrintAfter(TODO)

    • 在传递执行后打印 IR。

Python 前端​

前端仅需少量 API 即可创建并执行传递(完整实现见python/tvm/relax/transform/transform.py与python/tvm/ir/transform.py)。后端将根据提供的信息决定如何创建 Pass 对象。

PassContext​

Python 前端为 PassContext 提供了包装以支持 with 语法,并提供current 静态方法:

@tvm_ffi.register_object("transform.PassContext")
class PassContext(tvm.runtime.Object):
    def __enter__(self):
        _transform.EnterPassContext(self)
        return self

    def __exit__(self, ptype, value, trace, config):
        _transform.ExitPassContext(self)

    @staticmethod
    def current():
        """Return the current pass context."""
        return _transform.GetCurrentPassContext()

PassContext用于配置编译选项(优化级别、必需/禁用传递等),并可传入配置字典,以便不同传递读取需要的数据(如回退设备信息、循环展开步数/深度等)。若要从 config 中获取某项配置,其键名需通过TVM_REGISTER_PASS_CONFIG_OPTION 注册,例如循环展开传递:

TVM_REGISTER_PASS_CONFIG_OPTION("tir.UnrollLoop", UnrollLoopConfig);

详见src/tir/transforms/unroll_loop.cc。

Python 中的传递检测​

使用装饰器(python/tvm/ir/instrument.py)可以快速实现 PassInstrument。 推荐使用装饰器方式而非继承:

  • enter_pass_ctx:进入 PassContext 时执行;
  • exit_pass_ctx:退出 PassContext 时执行;
  • should_run:在传递执行前调用,返回该传递是否应执行;
  • run_before_pass:传递执行前调用;
  • run_after_pass:传递执行后调用。

可通过 :pytvm.transform.PassContext 的 instruments 参数注册实例。更多示例见use pass instrument教程。

覆盖当前 PassContext 中的检测器​

override_instruments 方法可覆盖当前 PassContext 中的 instruments。例如,当未显式创建新 PassContext 而直接运行传递时,仍可将检测器注册到全局上下文:

cur_pass_ctx = tvm.transform.PassContext.current()
# 覆盖 PassInstrument 实例
cur_pass_ctx.override_instruments([pass_inst])
mod = pass_seq(mod)
result = pass_inst.get_result()

注意:调用 override_instruments 时,旧检测器的 exit_pass_ctx会被调用,随后新检测器的 enter_pass_ctx 会被调用。

TVM Relay与Pass TVM Relay与Pass 本文介绍TVM的Relay,如何基于Relay构建一个Conv+BN+ReLU的小网络, TVM中的Pass的工作机制,并较为详细的介绍了RemoveUnusedFunctions,ToBasicBlockNormalForm,EliminateCommonSubexpr三种Pass。其中Relay部分的详细介绍大部分引用自官方文档: https://tvm.apache.org/docs/tutorials/get_started/introduction.html。 TVM 阅读详情

相关推荐

TVM Pass IR如何使用

TVM Pass IR如何使用 随着Relay / tir中优化遍数的增加,执行并手动维护其依赖关系变得很棘手。引入了一个基础结构来管理优化过程,并应用于TVM堆栈中IR的不同层。 Relay / tir程序的优化可以以各种粒度应用,即分别使用tvm.relay.transform.FunctionPass/ tvm.tir.transform.PrimFuncPass和的功能级别和模块级别tvm.transform.ModulePass。或者,用户可以依靠在tvm.transform.Sequential

吴建明wujianming_110117 836

【TVM 教程】如何使用 TVM Pass Infra

Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →<https://tvm.hyper.ai/>

HyperAI超神经 832

TVM学习(八)pass总结

什么是pass? Pass是TVM中基于relay IR进行的优化,目的是去除冗余算子,进行硬件友好的算子转换,最终能够提高硬件运行效率。由tensorflow等深度学习框架生成的图机构中,含有很多可以优化的算子,比如expand_dim,len等,其实在编译阶段完全可以优化掉,从而能够减少硬件的计算,以及避免出现硬件不支持的算子。 TVM中在include/tvm/ir/transform.h中对pass进行了抽象,主要包括PassContext,PassInfo,Pass,以及Sequential。其中

qq_33287871的博客 1823

【TVM 教程】如何使用 TVM Pass Instrument

​可以使用装饰器创建自定义 instrument 类。创建一个工具类(计算每次 Pass 引起的每个算子出现次数的变化)。可以在 Pass 之前和之后查看op.name来找到每个算子的名称,从而计算差异。# Pass 可以嵌套。# 使用堆栈来确保得到之前/之后正确的 pairs。# 弹出最新记录的 Pass。# 只记导致差异的 Pass。"""return ["""ret = {}else:# 某些 CallNode 可能没有“名称”,例如 relay.Functionreturn。

HyperAI超神经 1038

Python+Selenium实战:5分钟搞定快手评论区数据采集(附完整代码)

本文详细介绍了如何使用Python和Selenium快速采集快手评论区数据,提供完整的代码实现和优化方案。通过动态加载处理和智能等待策略,5分钟内即可构建高效的评论采集工具,适用于用户行为分析和内容挖掘等场景。

weixin_30415113的博客 344

使用WSL2安装ubuntu系统并配置深度学习环境

wsl2安装ubuntu部署深度学习环境的方法

u013358093的博客 2702

【TVM 教程】编写自定义 Pass

Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →https://tvm.hyper.ai/

HyperAI超神经 925

gitlab远程子仓库配置SSH - 保姆级教程

在网上搜索了一些方法,但是不够详细,走了好多弯路,所以记录下配置SSH的详细过程吧。

是菠萝的博客 1万+

【从零开始学深度学习编译器】八,TVM的算符融合以及如何使用TVM Pass Infra自定义Pass

对于一张有向图(可以有环)我们规定一个起点, 从点到图上另一个点可能存在很多条路径(下面将到简写为)。如果对于的任意一条路径中都存在一个点, 那么我们称点为的支配点(也可以称作是的必经点), 注意点不讨论支配点. 下面用表示离点最近的支配点。对于原图上除外每一个点, 从向建一条边, 最后我们可以得到一个以为根的树. 这个树我们就叫它"支配树"。这篇文章介绍了TVMPass Infra的一些实践例子,然后介绍了支配树和算符融合Pass。

生活需要深度 868

告别色差!用Python+TCS34725颜色传感器实现精准色彩还原(附完整校准代码)

本文详细介绍了如何利用Python和TCS34725颜色传感器实现专业级色彩还原方案。通过双阶校准法(白光校准和黑电平校准)和进阶的光照自适应技术,解决传感器原始数据不准的问题,并提供完整的校准代码和实战案例,帮助开发者实现ΔE<3的高精度色彩识别。

weixin_30836759的博客 209

逆向拆解dy接口a_bogus 1.0.1.19版本核心算法(纯算版)第二部分

本文深入解析了dy接口a_bogus 1.0.1.19版本的核心算法,重点介绍了逆向分析的基础方法论、魔改Base64编码识别与还原、随机数生成与位运算解析等关键技术。通过详细的代码示例和实用技巧,帮助开发者掌握逆向工程中的关键步骤,特别是针对a_bogus参数的生成逻辑和混淆处理。

weixin_29288313的博客 409

TVM Pass概述

use pass infra Design and Architecture Pass又称transform,每一个transform要么把现有程序转换并优化为一个等价的程序,要么把程序lower到下层。relay/transform包括很多优化模型用的pass,包括常量折叠(constant folding)和死代码删除(dead-code elimination)等。 这里拿tests/python/relay/test_pass_fold_constant.py里的单测作为例子: import num

Eurypterid的博客 1353

【图像去噪】论文复现:Mamba没Out!MaIR的Pytorch源码复现,跑通全流程,轻松解决环境配置问题,图文结合,明确MaIR创新点,与MambaIR对比,示意图与源码对应,清晰易懂,注释详细!

论文题目:MaIR: A Locality- and Continuity-Preserving Mamba for Image Restoration —— MaIR:用于图像恢复的局部性和连续性保持 Mamba【图像去噪】论文精读:MaIR: A Locality- and Continuity-Preserving Mamba for Image Restoration【图像去噪】论文复现:Man!

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1114

pass基础设施

Relay和TVM IR都包含一系列优化pass,用于改善模型的性能指标,如平均推断、内存占用或特定设备的功耗。有一套标准的优化和机器学习特有的优化,包括常量折叠、死代码消除、算子布局更改、算子融合、缓冲区处理和循环转换等。通过使用遍历期间和/或遍历之前收集的分析结果,将每个pass都被构造为ir-to-ir转换。然而,随着TVM的迅速发展,对这些pass进行更系统和更有效管理的需求变得越来越明显。另外,一个管理跨TVM栈不同层(如Relay和tir)的pass的通用框架,为开发人员快速原型化和将实现的pa

zx_ros的博客 1219

基于深度学习的道路裂缝检测系统完整教程

本文介绍了一种基于深度学习的道路裂缝检测系统完整解决方案。项目采用5466张高质量道路裂缝图像数据集,包含YOLO和Pascal VOC两种标注格式,覆盖多种道路场景。系统利用CNN和YOLO算法实现高效检测,相比传统人工巡检显著提升效率和准确性。文中详细阐述了数据集结构、环境配置和训练流程,包括数据预处理、智能分割策略和质量检查方法。该技术可及时发现道路裂缝隐患,降低维护成本,保障交通安全,为道路养护提供智能化解决方案。

FJN110的博客 298

R语言生存分析之限制性立方样条分析:样条回归、和多项式回归有什么不同?是否存在非线性关系、限制性立方样条cox回归模型

R语言生存分析之限制性立方样条分析:样条回归、和多项式回归有什么不同?是否存在非线性关系、限制性立方样条cox回归模型

statistics+insight+vista+power 635

TVM Pass 总结

介绍 tvm.relay.transform

fwx_x的博客 3162

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【从零开始学深度学习编译器】五,TVM Relay以及Pass简介

在前面几节的介绍中我们了解到了TVM是如何将ONNX前端模型转换为IR Module的,并且还剖析了TVM中的Relay算子和TOPI算子的扭转过程,知道了Relay算子的最终计算也是基于TOPI算子集合完成的。这几行代码展示了TVM的编译流程,在这个编译流程里面不仅包含了基于Relay IR进行的优化策略来去除冗余的算子(也叫Pass)还包含了将Relay程序编译成特定后端(这里是llvm)可以执行的代码(codegen)。

生活需要深度 960

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【TVM 教程】向 Relay 中添加 Compiler Pass

Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →https://tvm.hyper.ai/

HyperAI超神经 960

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

TVM Relay Pass探究

引言Relay 是 TVM 中十分重要的基础组件之一,用于对接不同格式的深度学习模型以及进行模型的 transform。深度学习编译器的核心功能就是进行各种各样的 transform 变换,这个变换过程部分是由 Pass 来实现。当需要遍历计算图时,底层究竟是如何执行的?本文打算一探究竟。1. 简介Pass 两层设计:TIR 层,基于target的优化,主要涉及 lower 到 target...

LF_AI的博客 962

【从零开始学深度学习编译器】七,万字长文入门TVM Pass

树的节点定义为在中,主要有以下几种类型:ConstantNode、VarNode、TupleNode、CallNode、LetNode、IfNode。这些Node都继承了在定义的,而又继承了/*!*//*!* \brief 所有非原始表达式的基节点。* RelayExpr 支持张量类型、函数和 ADT 作为* 一等公民。对应的生命周期* 对象由语言隐式管理。Expr cond;/*!/*!public:/*!*/Expr op;/*!/*!

生活需要深度 1049

ToolJet 实战:利用 `globals.currentUser` 属性按用户身份动态禁用组件

在 ToolJet 中构建内部工具或业务应用时,常常需要根据"当前登录用户是谁、属于哪个用户组"来决定界面上某个组件的可用状态。本文将围绕 ToolJet 应用构建器的全局变量 `globals.currentUser`,系统讲解其暴露的 `email`、`firstName`、`lastName`、`groups`、`metadata` 等属性,并以"非管理员用户禁用按钮"为完整案例,演示如何在

gitblog_01192的博客 549

TVM 学习指南(个人版)

最近粗略的看完了天奇大佬的MLC课程(顺便修了一些语法和拼写错误,也算是做了微弱的贡献hh),对TVM的近期发展有了一些新的认识。之前天奇大佬在《新一代深度学习编译技术变革和展望》一文中(链接:https://zhuanlan.zhihu.com/p/446935289)讲解了TVM Unify也即统一多层抽象的概念。这里的统一多层抽象具体包括AutoTensorization用来解决硬件指令声明和张量程序对接,TVM FFI(PackedFunc)机制使得我们可以灵活地引入任意的算子库和运行库函数并且在各

I good vegetable a! 8519
上一篇: 【Triton 教程】triton_language.swizzle2d
下一篇: 在线教程丨微软开源3D生成模型TRELLIS.2,3秒生成高分辨率的全纹理资产
HyperAI超神经
博客等级 码龄7年 8873粉丝 1753原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值